在TypeScript(角度)中打开下载链接 [英] Open Download link In TypeScript (Angular)

查看:52
本文介绍了在TypeScript(角度)中打开下载链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题很简单.我有此接口是使用Angular构建的.当我单击1时,它将打开弹出窗口,然后当我单击2时,它将调用一个函数:

My problem is simple. I have this interface built with Angular. When I click on 1 it opens the popup, and then when I click on 2 it calls a function:

showDownloadLink(ev, name) {
    let config = new MdDialogConfig()
        .textContent('<a href="http://www.google.fr">lol</a>')
        .clickOutsideToClose(false)
        .title('Would you like to delete your debt?')
        .ariaLabel('Lucky day')
        .ok('Please do it!')
        .cancel('Sounds like a scam')
        .targetEvent(ev);
    this.dialog.open(MdDialogBasic, this.element, config)
        .then((ref: MdDialogRef) => {
            ref.whenClosed.then((result) => {
                if (result) {
                    var url = this._Service.getDownloadLink(name);
                    console.log(url);
                    //window.open(url,'Download');
                    //this.downloadURI(url );
                }
                else {
                    this.status = 'You decided to keep your debt.';
                }
            })
        });
}

downloadURI(uri) {
    var link = document.createElement("a");
    link.href = uri;
    link.click();
}

使用的模块为 ng2-material ,并带有确认"对话框"按钮.

The module used is ng2-material with a "confirm dialog" button.

var url在控制台中为我提供了一个很好的url console.log(url);=> ,当我单击控制台中显示的链接时,它会很好地下载文件:)

The var url gives me a good url in the console console.log(url); => when I click on the link shown in the console, it downloads the file well :)

问题在于下载未通过代码触发.

The problem is that the download is not triggered in code.

移动一些东西后

Dashboard.components.ts:

Dashboard.components.ts :

downloadFile(url,file) {
    this._Service.getDownloadFile(url,file);
}

像以前一样,在 show download 链接中调用downloadFile.

The downloadFile is called in the show download link like before.

在_service.ts中:

In the _service.ts:

import {Injectable} from "angular2/core";
import {S3Object} from "./s3object";
import {Observable} from "rxjs/Observable";
import {Http, Headers, Response} from "angular2/http";
import "rxjs/Rx";
import {CredService} from "./cred.service";
//mettre les parenthèses !!
@Injectable()
export class Service {

    private serviceUrl = 'url';
    private token;
    private headers = new Headers();
    private credS;

    constructor(private http:Http, private cred:CredService) {
        this.credS = cred;
        this.token = cred.getToken();
        this.headers.append('Authorization', 'bearer ' + this.token);
        this.headers.append('Content-Type', 'application/json');
    }

    getDownloadLink(path:string){
        var opUrl = 'download.json?objectKey='+path;
        var urlRes = "";
        this.http.get(
            this.serviceUrl + opUrl,
            { headers: this.headers }
        )
            .map(res => res.text())
            .subscribe(
                data => urlRes = data,
                err => console.log(err),
                () => console.log(urlRes)
            );

        //console.log(urlRes);
        return urlRes;
    }

    getDownloadFile(url:string, file:string) {
        this.http.get(url).subscribe(
            (response) => {
                var blob = new Blob([response._body], {type: "application/text"});
                var filename = file;
                saveAs(blob, filename);
            });
    } 
}

和一个customBrowserXhr.ts文件:

And a customBrowserXhr.ts file:

import {Injectable} from 'angular2/core';
import {BrowserXhr} from 'angular2/http';

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
    constructor() {}
    build(): any {
        let xhr = super.build();
        xhr.responseType = "blob";
        console.log("it's cool bro ! ");
        return <any>(xhr);
    }
}

我的控制台功能执行的日志(我用代码中的URL替换了正确的url)

My console Log of the execution of the function ( I replaced the correct url by URL in the code)

test url ddl before : "URL/Desert.jpg?serieofparams"
test name ddl before : Desert.jpg

功能:

downloadFile(url,file) {
    console.log('test url ddl before : ' + url);
    console.log('test name ddl before : ' + file);
    this.http.get(url).subscribe(
        (response) => {
            var blob = new Blob([response._body], {type: "image/jpeg"});
            var filename = file;
            saveAs(blob, filename);
        });
}

但是我得到了这个错误:

But I got this error:

Failed to load resource: the server responded with a status of 404 (Introuvable) http://localhost:8080/context/%22URL/Desert.jpg?serieofparams%22
angular2.dev.js:23740 EXCEPTION: [object Object]

有人知道造成这种情况的原因吗?路由模块是否可以这样做?在此Plunkr 上,它运行良好.

Does anyone have any idea of what is causing this? Is it possible that the routing module does this? On this Plunkr it's working perfectly.

推荐答案

一种方法是通过AJAX请求加载图像,然后利用

An approach would be to load the image through an AJAX request and then leverage the FileSaver library to open the download dialog.

这里是一个样本.您需要扩展 BrowserXhr 类以设置响应类型.

Here is a sample. You need to extend the BrowserXhr class to set the response type.

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
  constructor() {}
  build(): any {
    let xhr = super.build();
    xhr.responseType = "blob";
    return <any>(xhr);
  }
}

然后,您可以利用此类执行请求以获取图像内容:

Then you can leverage this class to execute the request to get the image content:

@Component({
  selector: 'download',
  template: `
    <div (click)="downloadFile() ">Download</div>
  `,
  providers: [
    provide(CustomBrowserXhr, 
      { useClass: CustomBrowserXhr }
  ]
})
export class DownloadComponent {
  @Input()
  filename:string;

  constructor(private http:Http) {
  }

  downloadFile() {
    this.http.get(
      'https://mapapi.apispark.net/v1/images/'+this.filename).subscribe(
        (response) => {
          var mediaType = 'application/pdf';
          var blob = new Blob([response._body], {type: mediaType});
          var filename = 'test.pdf';
          saveAs(blob, filename);
        });
    }
}

此替代项(设置响应类型)仅适用于此组件(引导应用程序时请不要忘记删除相应的提供),因为我在提供程序的 providers 属性中设置了提供程序零件.下载组件可以这样使用:

This override (setting the response type) would only applies for this component (don't forget to remove the corresponding provide when bootstrapping your application) because I set the provider in the providers attribute of the component. The download component could be used like that:

@Component({
  selector: 'somecomponent',
  template: `
    <download filename="'Granizo.pdf'"></download>
  `
  , directives: [ DownloadComponent ]
})

有关更多详细信息,请参见以下答案:

See this answer for more details:

这篇关于在TypeScript(角度)中打开下载链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆