【问题标题】:How to manage an observable stream during the lifetime of a router component?如何在路由器组件的生命周期内管理可观察流?
【发布时间】:2017-02-25 18:11:04
【问题描述】:

我希望订阅一个 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$ 而不是从订阅中调用服务方法。

【问题讨论】:

    标签: angular rxjs


    【解决方案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(); }
    

    这样,当您导航离开时,订阅会停止,当您导航到该路线时,订阅会重新上线。

    【讨论】:

      【解决方案2】:

      在您的数据服务中可能是这样的:

      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();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-19
        • 2019-04-08
        • 2021-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多