如何在路由器组件的生命周期内管理可观察流?

时间:2017-02-25 18:11:04

标签: angular rxjs

我希望订阅一个observable并在其上使用一些方法来确保它被去除并且先前的请求被取消

private _allBulls = new BehaviorSubject<Sire[]>([]); 
allBulls$ = this._allBulls.asObservable();

private apiChange = new Subject<ApiChange>();
apiChange$ = this.apiChange.asObservable().distinctUntilChanged().debounceTime(1000);

我已经到了这里,我可以订阅我的组件,然后从组件中调用此方法

this.subscription = this.selectionService.apiChange$.subscribe(
(data) => {
  this.selectionService.getSireData(data); 
})

方法getSireData

getSireData(apiChange: ApiChange) {
  console.log("getSireData")

  this.updateApiSettings(apiChange);

  const headers = new Headers({'Content-Type': 'application/json'})

  options = new RequestOptions({ headers: headers});

  this.http
   .post(`${this.baseUrl}SireSearch/Scope/Filtered`, this.apiSettings, options)
   .map(this.extractData)
  .subscribe(data => this._allBulls.next(data))
}

另一个组件中的订阅,以进行反映可观察

的更改
this.selectionService.allBulls$.subscribe(() => this.selectionService.applyGridSettings());

我不能使用.switch或.switchMap运算符,因为它需要返回的observable。所以我认为我需要提出一个不同的结构。我也更愿意只订阅apiChange $而不是从订阅中调用服务方法。

2 个答案:

答案 0 :(得分:1)

也许是这样的,在您的数据服务中:

class YourServiceClass {
    private updateSireOnApiChange$ = this.serviceWithApiChanges.apiChange$
        .switchMap(apiSettings => {
            const headers = new Headers({'Content-Type': 'application/json'})
            const options = new RequestOptions({ headers: headers});

            return this.http
                .post(`${this.baseUrl}SireSearch/Scope/Filtered`, this.apiSettings, options)
                .map(this.extractData)
        })
        .do(data => this._allBulls.next(data));

    constructor(private http: Http, private serviceWithApiChanges: ServiceWithApiChanges) {
        this.updateSireOnApiChange$
            .catch(() => this.updateSireOnApiChange$) // just resubscribe to a fresh stream on any error to keep this active forever
            .subscribe();
    }
}

答案 1 :(得分:1)

当你看到

对于同一进程,

this.selectionService 多次从组件中使用,这可能意味着您希望将整个逻辑放在服务中。这样就可以为服务用户抽象出内部逻辑。

此外,将它放在一起将允许您在httpRequest上创建switchMap并取消之前挂起的请求。请注意,已取消的请求仍将在服务器端运行,但至少您的客户端将丢弃任何过时请求的结果。

在您的服务中,您需要

private apiChange = new Subject<ApiChange>();
apiChange$ = this.apiChange
.asObservable()
.distinctUntilChanged()
.debounceTime(1000)
.switchMap( (data) => { 
  this.updateApiSettings(data);

  const headers = new Headers({'Content-Type': 'application/json'}), 
  const options = new RequestOptions({ headers: headers}); 

  return this.http
             .post(`${this.baseUrl}SireSearch/Scope/Filtered`, this.apiSettings, options) 
}) 
.map(this.extractData); 

以及将对服务进行订阅的服务方法,如:

startSubscription() { return this.selectionService.allBulls$.subscribe(() => this.selectionService.applyGridSettings()); }

并且在组件中,您只想在初始化时订阅它并在组件被销毁时取消订阅,所以

ngOnInit() {this.subscription = this.service.startSubscription();} 
ngOnDestroy() {this.subscription.unsubscribe(); }

这种方式当您离开时,订阅停止,当您导航到该路线时,订阅将重新开始。