Angular:當多個訂閱(BehaviorSubjects)全部定義時調用方法

[英]Angular: Invoke method when multiple subscriptions (BehaviorSubjects) are all defined


I've set up a "global" service, to share parameters across components in my Angular app:

我已經設置了一個“全局”服務,在我的Angular應用程序中跨組件共享參數:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class ParameterService {

  param1 = new BehaviorSubject(null);
  publishParam1(data: number) {
    this.param1.next(data);
  }

  param2 = new BehaviorSubject(null);
  publishParam2(data: number) {
    this.param2.next(data);
  }

}

Components which need either or both of these parameters can subscribe, and be notified when these change:

需要這些參數中的一個或兩個的組件可以訂閱,並在這些更改時得到通知:

  private subscriptions: Array<Subscription> = [];
  param1: number; // keep local copies of the params
  param2: number;

  ngOnInit(): void {

    this.subscriptions.push(this._parameterService.param1.subscribe(
      data => {
          console.log("param1 changed: " + data);
          if (data != null) {
            this.param1 = data;
            // NB! this.param2 may be undefined!
            this.getDataFromAPI(this.param1, this.param2);
        }
      }
    ));

    this.subscriptions.push(this._parameterService.param2.subscribe(
      data => {
          console.log("param2 changed: " + data);
          if (data != null) {
            this.param2 = data;
            // NB! this.param1 may be undefined!
            this.getDataFromAPI(this.param1, this.param2);
        }
      }
    ));
  }

  ngOnDestroy() {
    // https://stackoverflow.com/questions/34442693/how-to-cancel-a-subscription-in-angular2
    this.subscriptions.forEach((subscription: Subscription) => {
            subscription.unsubscribe();
        });
  }

param1 and param2 are initialized by AppComponent, asynchronously, so the components subscribing to both parameters will be "notified" (receive the values) in arbitrary order. getDataFromAPI should get new data whenever either parameter changes, so both subscriptions call the method, but the other parameter may still be undefined.

param1和param2由AppComponent異步初始化,因此訂閱這兩個參數的組件將以任意順序“通知”(接收值)。每當任一參數更改時,getDataFromAPI都應獲取新數據,因此兩個訂閱都會調用該方法,但另一個參數可能仍未定義。

Obviously, this can easily be fixed by simply checking if the other parameter is defined before invoking getDataFromAPI, but I'm wondering what's the best way to handle this (surely common) scenario? Should I use promises or await to ensure that getDataFromAPI is only invoked when both (all) parameters are defined?

顯然,通過在調用getDataFromAPI之前簡單地檢查是否定義了其他參數,可以很容易地解決這個問題,但我想知道處理這個(肯定是常見的)場景的最佳方法是什么?我應該使用promises還是等待確保僅在定義了兩個(所有)參數時調用getDataFromAPI?

One simple idea which came to mind is to ensure the ParameterService only contains a single parameter; i.e. wrap param1 and param2 in some "state class":

想到一個簡單的想法是確保ParameterService只包含一個參數;即在一些“州級”中包裝param1和param2:

export class StateObject {
    param1: number;
    param2: number;

    constructor() { }
}

such that ParameterService becomes,

使ParameterService成為,

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { StateObject } from './stateobject';

@Injectable()
export class ParameterService {

  state = new BehaviorSubject(null);
  publishState(data: StateObject) {
    this.state.next(data);
  }
}

1 个解决方案

#1


1  

You could try:

你可以嘗試:

let subscription  = Rx.Observable.combineLatest(
    this._parameterService.param1,
    this._parameterService.param2
  )
  .subscribe(data => {
      console.log("param1 or param2 changed: " + data);
      let [p1, p2] = data;
      this.getDataFromAPI(this.param1 = p1, this.param2 = p1);
    })
);

Or with projection function:

或者具有投影功能:

let subscription  = Rx.Observable.combineLatest(
    this._parameterService.param1,
    this._parameterService.param2,
    (p1, p2) => { p1: p1, p2: p2 }
  )
  .subscribe(data => {
      console.log("param1 or param2 changed: " + data);
      this.getDataFromAPI(this.param1 = data.p1, this.param2 = data.p2);
    })
);

combineLatest API reference

combineLatest API參考


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2017/09/06/729e621bf6f4aabfab605062f53f67ef.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com