我认为您的问题比乍一看更棘手;-) 事实上,XHR 不支持流式传输,因此当在 subscribe 方法中注册的第一个回调被调用时,您已经收到了所有数据。
也就是说 XHR 支持 onprogress 事件(请参阅此 plunkr:http://plnkr.co/edit/8MDO2GsCGiOJd2y2XbQk?p=preview)。这允许获取有关下载进度的提示。 Angular2 不支持开箱即用,但您
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor(private service:ProgressService) {}
build(): any {
let xhr = super.build();
xhr.onprogress = (event) => {
service.progressEventObservable.next(event);
};
return <any>(xhr);
}
}
并使用扩展覆盖BrowserXhr 提供程序:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
进度服务可以这样实现:
export class ProgressService {
progressEventObservable:Subject<any> = new Subject();
}
您的服务可以订阅进度服务,以便在下载实际开始时收到通知(即第一次为请求调用progressEventObservable 的next 方法):
getList() {
var subscription = this.progressService.subscribe(event => {
if (!this.spinner) {
this.spinner = true;
}
});
this._http.get('../fake-data/someFile.json')
.map(response => response.json())
.do(val => this.spinner = true)
.subscribe(
data => {
this.dataStore.meetingList = data;
this.meetingListObserver.next(this.dataStore.meetingList);
},
err => (...),
() => {
this.spinner = false;
subscription.unsubscribe();
})
);
}
编辑
如果您想在组件而不是服务中使用微调器。您可以使用专用的 observable / subject,如下所述:
spinner$: Subject<boolean> = new Subject();
spinner: boolean = false;
getList() {
var subscription = this.progressService.subscribe(event => {
if (!this.spinner) {
this.spinner = true;
this.spinner$.next(this.spinner); // <-------
}
});
this._http.get('../fake-data/someFile.json')
.map(response => response.json())
.do(val => this.spinner = true)
.subscribe(
data => {
this.dataStore.meetingList = data;
this.meetingListObserver.next(this.dataStore.meetingList);
},
err => (...),
() => {
this.spinner = false;
this.spinner$.next(this.spinner); // <-------
subscription.unsubscribe();
})
);
}
该组件可以订阅spinner$ 以获得更改通知:
@Component({
(...)
})
export class SomeCOmponent {
constructor(private meetingService:MeetingService) {
this.meetingService.spinner$.subscribe((spinner) {
this.isLoaderEnabled = spinner;
});
}
}