我希望在数据开始从API下载时打开我的加载程序图标(例如微调器)isLoaderEnabled,并在成功接收时将其关闭.什么是关闭它的正确方法?
这是我的以下代码.
我的组件:
this.isLoaderEnabled = true; this.meetingService.getList();
我的服务:
getList() { this._http.get('../fake-data/someFile.json') .map(response => response.json()) .subscribe( data => { this.dataStore.meetingList = data; this.meetingListObserver.next(this.dataStore.meetingList); },err => console.log('>>>','Could not load meetings list. Error: ',err),() => console.log('>>>','Done with getting meetings list.') ); }
谢谢.
解决方法
我认为你的问题比第一眼看上去最棘手;-)事实上,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的下一个方法):
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); },() => { this.spinner = false; this.spinner$.next(this.spinner); // <------- subscription.unsubscribe(); }) ); }
@Component({ (...) }) export class SomeCOmponent { constructor(private meetingService:MeetingService) { this.meetingService.spinner$.subscribe((spinner) { this.isLoaderEnabled = spinner; }); } }