【问题标题】:Angular 2 download file from rest service来自休息服务的Angular 2下载文件
【发布时间】:2017-04-23 13:25:50
【问题描述】:

我有 Angular 2 客户端,可以从 rest 服务下载文件:

 downloadAPK(projectName: string): void {
    this.projectService.downloadAppFile(projectName).subscribe(blobContent => {
        var a = document.createElement("a");
        a.setAttribute('style', 'display:none;');
        document.body.appendChild(a);
        var url = window.URL.createObjectURL(blobContent);
        a.href = url;
        a.download = projectName + '.apk';
        a.click();
    });

}

客户端代码:

<div class="subTitleStatus">Ready 
    <a style="cursor:pointer" (click)="downloadAPK(project.name)"><i class="glyphicon glyphicon-download-alt"></i></a>
</div>

服务代码:

downloadAppFile(projectName: String): any {
    return this._http.get(this._productUrl + "/downloadAppFile/" + projectName,
        {responseType: ResponseContentType.Blob})
        .map(res => res.blob())
        .catch(this.handleError);
}

问题是在客户端完成下载文件之前,用户没有任何迹象表明下载已开始。 我说的是大文件

当用户点击下载链接直到完成下载时,如何更改客户端代码以显示下载百分比?

谢谢

【问题讨论】:

  • 您需要有一个 onClick 事件处理程序。由于您没有在 ui 模板或实际事件上提供太多代码,因此我无法为您提供太多帮助。
  • 我更新我的问题
  • 服务中有什么?是否有某种变量可以显示已发送给客户端的数量以及文件的大小?
  • 我的问题更新的服务代码,文件大小约30MB

标签: angular


【解决方案1】:

你为什么不下载文件作为链接?

第一个解决方案(下载链接)

您不需要通过服务下载,只需在新标签中加载链接,浏览器就会下载它(如果您有正确的标题,例如来自服务器的附件标题)

    <div class="subTitleStatus">Ready 
        <a style="cursor:pointer" [attr.href]="downloadAPK(project.name)" target="_blank">
            <i class="glyphicon glyphicon-download-alt"></i>
        </a>
    </div>

这就是服务

    downloadAppFile(projectName: String): any {
        return this._productUrl + "/downloadAppFile/" + projectName;
    }

第二种解决方案(通过 JavaScript): 您有另一个解决方案,但需要在服务器端进行一些更改 请阅读How to get progress from XMLHttpRequest 更具体到 angular2 Angular 2 HTTP Progress bar

第三种解决方案(通过 Javascript - 不确定)

downloadAppFile(projectName: String, start: ()=>void, stop: ()=>void): any {
    return this._http.get(this._productUrl + "/downloadAppFile/" + projectName,
        {responseType: ResponseContentType.Blob})
        .do(start)
        .map(res => res.blob())
        .finally(stop)
        .catch(this.handleError);
}

并在您的控制器中定义停止和启动

开始可以是这样的:

() => { this.showSpinner = true }

然后停止:

() => { this.showSpinner = false }

所以最终的控制器是这样的:

downloadAPK(projectName: string): void {
    showSpinner = false;
    start = () => { this.showSpinner = true }
    stop = () => { this.showSpinner = false }
    this.projectService.downloadAppFile(projectName, this.start, this.stop).subscribe(blobContent => {
        var a = document.createElement("a");
        a.setAttribute('style', 'display:none;');
        document.body.appendChild(a);
        var url = window.URL.createObjectURL(blobContent);
        a.href = url;
        a.download = projectName + '.apk';
        a.click();
    });

}

在视图中只需添加一个微调器并根据this.showSpinner 变量显示/隐藏它

如果您不从服务器发送文件大小,则无法确定下载百分比

更新

添加的第三个解决方案

第一个解决方案基于Angular2 set href in attribute directive更新

在第一个解决方案中,类型和 href 更改为 [attr.href]

【讨论】:

  • 我不想改变服务器端,href="downloadAPK(project.name)" 在 Angular 2 中不起作用
  • 第二个解决方案怎么样,如果第二个解决方案由于服务器端更改而对您不利,唯一的解决方案是不确定的进度/微调器,您可以从 Observable HTTP 调用的“do”部分开始并在完成/最终部分停止
猜你喜欢
  • 2018-05-26
  • 2018-02-09
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
相关资源
最近更新 更多