问题描述
所以我试图根据我的ajax调用创建一个准确的进度条,以使其充满.
so I'm trying to make an accurate progress bar that fills up based on the my ajax call.
此有帮助,但我认为自编写以来,情况可能有所变化.
This helped but I think that perhaps things have changed a little since it was written.
因此,我有自己的CustomBrowserXhr,我已将其添加到我的App Module提供程序中以对BrowserXhr进行控制:-
So I have my CustomBrowserXhr that I've added to my App Module providers to ovverride the BrowserXhr:-
@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);
}
}
然后我有一个非常基本的进度服务,其他组件也可以订阅:-
I then have a very basic progress service which other components can subscribe to:-
@Injectable()
export class ProgressService {
progressEventObservable:Subject<any> = new Subject();
progressEvent$ = this.progressEventObservable.asObservable();
}
我以为我可以进行http调用,并且会看到控制台日志浏览器内部事件覆盖"-因为它只是出现错误"EXCEPTION:browserXHR.build不是函数".有人可以告诉我这里出了什么问题吗?
I thought that I could just make http calls and I would see the console log "event inside browser override" - as it is I just get the error "EXCEPTION: browserXHR.build is not a function". Can someone shed some light one what's going wrong here please?
谢谢.
推荐答案
编辑:我将调用添加到super();
,并将一些有用的东西附加到了事件对象上.
I added the call to super();
and attached a few useful things to the event object.
感谢您的帮助.这对我有用.为了简洁起见,我将这两种服务都放在一个文件中:
Thanks for your help. This works for me. I threw both of these services into one file for brevity:
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);
}
}
正如您所描述的,我将这两项服务添加到了我的主模块中:
I added the two services to my main module, just as you described:
providers: [
ProgressService,
{ provide: BrowserXhr, useClass: CustomBrowserXhr }
],
bootstrap: [ AppComponent ]
它已按预期登录到控制台.然后,在我上载文件的组件中,我不得不强制进行更改检测,但否则它可以很好地工作:
It logged to the console as expected. Then, in the component where I upload files, I had to force change detection, but it otherwise works fine:
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();
});
}
我试图使其与异步管道一起使用,但它仅在最后一个事件上更新.你觉得呢?
I tried to get it to work with async pipe, but it was only updating on the last event. What do you think?
这篇关于Angular 2.0如何扩展BrowserXhr以创建进度栏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!