Angular2/RxJS-从Http观察到数据后更新变量 [英] Angular2 / RxJS - updating variable after getting data from Http observable

查看:76
本文介绍了Angular2/RxJS-从Http观察到数据后更新变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在从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();
}

您的服务可以订阅进度服务,以便在下载实际开始时(即,第一次为请求调用progressEventObservablenext方法)时得到通知:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆