Angular2/RxJS-从Http观察到数据后更新变量 [英] Angular2 / RxJS - updating variable after getting data from Http observable
问题描述
我想在从API开始下载数据时打开加载程序图标(例如微调框)isLoaderEnabled
,并在成功接收到数据后将其关闭.将其关闭的正确方法是什么?
I would like to turn on my loader icon (e.g. spinner) isLoaderEnabled
when data starts to download from API and turn it off when successfully received. What would be a proper way to turn it off?
这是我的以下代码.
我的组件:
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
方法被称为您已经接收到所有数据.
I think that your issue is trickiest than it appears at a first sight ;-) In fact, XHR doesn't support streaming so when the first callback registered within the subscribe
method is called you already received all the data.
表示XHR支持onprogress
事件(请参见以下代码:punkr: http://plnkr. co/edit/8MDO2GsCGiOJd2y2XbQk?p = preview ).这样可以获取有关下载进度的提示. Angular2不支持此功能,但您
That said XHR supports the onprogress
event (see this plunkr: http://plnkr.co/edit/8MDO2GsCGiOJd2y2XbQk?p=preview). This allows to get hints about the progress of the download. This isn't supported out of the box by Angular2 but you
@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
提供程序:
and override the BrowserXhr
provider with the extended:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
进度服务可以通过以下方式实现:
The progress service could be implemented this way:
export class ProgressService {
progressEventObservable:Subject<any> = new Subject();
}
您的服务可以订阅进度服务,以便在下载实际开始时(即,第一次为请求调用progressEventObservable
的next
方法)时得到通知:
Your service could subscribe on the progress service to be notified when the download actually starts (i.e. the first time the next
method of progressEventObservable
is called for the request):
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();
})
);
}
修改
如果要在组件而不是服务中使用微调框.您可以使用专用的可观察的/主题,如下所述:
If you want to use the spinner within the component and not the service. You could use a dedicated observable / subject, as described below:
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$
上订阅以通知更改:
The component can subscribe on spinner$
to be notified of changes:
@Component({
(...)
})
export class SomeCOmponent {
constructor(private meetingService:MeetingService) {
this.meetingService.spinner$.subscribe((spinner) {
this.isLoaderEnabled = spinner;
});
}
}
这篇关于Angular2/RxJS-从Http观察到数据后更新变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!