Angular2/RxJS - 从Http observable获取数据后更新变量

be-*_*ied 5 typescript angular

我希望isLoaderEnabled在数据开始从API下载时打开我的加载程序图标(例如微调器),并在成功接收时将其关闭.什么是关闭它的正确方法?

这是我的以下代码.

我的组件:

this.isLoaderEnabled = true;
this.meetingService.getList();
Run Code Online (Sandbox Code Playgroud)

我的服务:

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.')
    );
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Thi*_*ier 8

我认为你的问题比第一眼看上去最棘手;-)事实上,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);
  }
}
Run Code Online (Sandbox Code Playgroud)

BrowserXhr使用扩展覆盖提供者:

bootstrap(AppComponent, [
  HTTP_PROVIDERS,
  provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
Run Code Online (Sandbox Code Playgroud)

进度服务可以这样实现:

export class ProgressService {
  progressEventObservable:Subject<any> = new Subject();
}
Run Code Online (Sandbox Code Playgroud)

您的服务可以订阅进度服务,以便在下载实际开始时通知(即第一次为请求调用next方法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();
      })
    );
}
Run Code Online (Sandbox Code Playgroud)

编辑

如果要在组件中使用微调器而不是服务.您可以使用专用的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();
      })
    );
}
Run Code Online (Sandbox Code Playgroud)

组件可以订阅spinner$以通知更改:

@Component({
  (...)
})
export class SomeCOmponent {
  constructor(private meetingService:MeetingService) {
    this.meetingService.spinner$.subscribe((spinner) {
      this.isLoaderEnabled = spinner;
    });
  }
}
Run Code Online (Sandbox Code Playgroud)