Angular 2.0如何扩展BrowserXhr以创建进度条?
所以,我正试图根据我的ajax调用创建一个准确的进度条 帮助,但我认为,也许事情已经改变了一点,因为它是书面的 因此,我将我的CustomBrowserXhr添加到我的应用程序模块提供程序中,以覆盖BrowserXhr:-Angular 2.0如何扩展BrowserXhr以创建进度条?,angular,Angular,所以,我正试图根据我的ajax调用创建一个准确的进度条 帮助,但我认为,也许事情已经改变了一点,因为它是书面的 因此,我将我的CustomBrowserXhr添加到我的应用程序模块提供程序中,以覆盖BrowserXhr:- @Injectable() export class CustomBrowserXhr extends BrowserXhr { constructor(private service: ProgressService) {} build(): any {
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor(private service: ProgressService) {}
build(): any {
let xhr = super.build();
xhr.onprogress = (event) => {
console.log(event, "event inside browser override");
this.service.progressEventObservable.next(event);
};
return <any>(xhr);
}
}
@Injectable()
导出类CustomBrowserXhr扩展了BrowserXhr{
构造函数(私有服务:ProgressService){}
build():任何{
设xhr=super.build();
xhr.onprogress=(事件)=>{
日志(事件,“浏览器覆盖内的事件”);
this.service.progressEventObservable.next(事件);
};
返回(xhr);
}
}
然后,我有一个非常基本的进度服务,其他组件可以订阅该服务:-
@Injectable()
export class ProgressService {
progressEventObservable:Subject<any> = new Subject();
progressEvent$ = this.progressEventObservable.asObservable();
}
@Injectable()
出口级服务{
progressEventObservable:主题=新主题();
progressEvent$=this.progressEventObservable.asObservable();
}
我以为我可以进行http调用,然后我会看到控制台日志“浏览器覆盖内的事件”-事实上,我只是得到了错误“EXCEPTION:browserXHR.build不是一个函数”。有人能告诉我这里出了什么问题吗
提前感谢。编辑:我添加了对
super()的调用代码>并将一些有用的内容附加到事件对象
谢谢你的帮助。这对我有用。为了简洁起见,我将这两个服务都放在一个文件中:
import { Injectable } from '@angular/core';
import { BrowserXhr } from '@angular/http';
import { Subject } from 'rxjs/Rx';
@Injectable()
export class ProgressService {
progressEventObservable: Subject<any> = new Subject();
progressEvent$ = this.progressEventObservable.asObservable();
}
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor(private service: ProgressService) { super(); }
build(): any {
let xhr = super.build();
let startTime = Date.now();
xhr.upload.onprogress = (event) => {
let timeElapsed = Date.now() - startTime;
let uploadSpeed = event.loaded / (timeElapsed / 1000);
let timeRemaining = Math.ceil(((event.total - event.loaded) / uploadSpeed));
event.uploadTimeRemaining = timeRemaining;
event.uploadSpeed = (uploadSpeed / 1024 / 1024).toFixed(2);
event.percentCompleted = ((event.loaded / event.total) * 100).toFixed(0);
console.log(event, "event inside browser override");
this.service.progressEventObservable.next(event);
};
return <any>(xhr);
}
}
它按预期登录到控制台。然后,在我上传文件的组件中,我必须强制进行更改检测,但在其他方面效果良好:
constructor(
private cdr: ChangeDetectorRef,
private service: ProgressService
) {
this.service.progressEvent$.subscribe(event => {
this.progress = event.percentCompleted;
this.speed = event.uploadSpeed;
this.timeRemaining = event.uploadTimeRemaining;
this.cdr.detectChanges();
});
}
我试图让它与异步管道一起工作,但它只是在最后一个事件中更新。你觉得怎么样?你能找到解决方案吗?@kmansoor不,对不起,伙计,这是一个很好的选择,所以我在最后期限前离开了。如果你破解了它,请告诉我:)如果你能告诉我“ProgressServcie”是否正确地注入到CustomBrowserXhr的构造函数中,我会非常感激的?我有一个类似的设置,但是ProgressService的注入失败了。谢谢。@kmansoor-这已经得到了回答,请看下面。看起来不错,伙计,你需要一个super()代码>调用CustomBrowserXhr构造函数,但除此之外,它现在对我有效。我将xhr.upload.onprogress
更改为xhr.onprogress
,因为我需要所有xhr调用的进度。IDE确实要求一个super();呼叫无论有无,这都有效。我还没有检查呼叫或不呼叫的惩罚是什么,但我计划在本周这样做。是的,你不必这么做。这只是一个良好的实践,在这个特定的用例中不会造成伤害。你能创建一个plunkr吗?
constructor(
private cdr: ChangeDetectorRef,
private service: ProgressService
) {
this.service.progressEvent$.subscribe(event => {
this.progress = event.percentCompleted;
this.speed = event.uploadSpeed;
this.timeRemaining = event.uploadTimeRemaining;
this.cdr.detectChanges();
});
}