web-dev-qa-db-ja.com

Angular 2サービスの変更をリッスンするコンポーネント

変更の検出に関する簡単な質問があります。

内部にブール値を持つコンポーネントと(グローバル)サービスがあります。コンポーネントがそのブール値をリッスンし、そのブール値が変更された場合に関数を実行するにはどうすればよいですか?

ありがとう!

24
Han Che

そのブール値の変更方法に応じて、サービスでObservable<boolean>として公開し、コンポーネントでそのストリームをサブスクライブできます。サービスは次のようになります。

@Injectable()
export class MyBooleanService {
    myBool$: Observable<boolean>;

    private boolSubject: Subject<boolean>;

    constructor() {
        this.boolSubject = new Subject<boolean>();
        this.myBool$ = this.boolSubject.asObservable();
    }

    ...some code that emits new values using this.boolSubject...
}

次に、コンポーネントに次のようなものがあります。

@Component({...})
export class MyComponent {
    currentBool: boolean;

    constructor(service: MyBooleanService) {
        service.myBool$.subscribe((newBool: boolean) => { this.currentBool = newBool; });
    }
}

そのbool値で何をする必要があるかに応じて、コンポーネントを更新するために他のことをする必要があるかもしれませんが、これはオブザーバブルの使用の要点です。メモリーリークや予期しない副作用を防ぐために、ある時点でmyBool $ストリームからサブスクライブを解除することに注意してください。

別のオプションは、コンストラクターでストリームに明示的にサブスクライブする代わりに、テンプレート内で非同期パイプを使用することです。これにより、サブスクリプションが自動的に破棄されます。繰り返しますが、それは、bool値を使用して正確に何をする必要があるかによって異なります。

33
Sam Storie

サムの答えは完全に正しいです。 TypeScriptセッターを利用して、イベントの変更を自動的にトリガーすることもできます。

@Injectable()
export class MyBooleanService {
    myBool$: Observable<boolean>;

    private boolSubject: Subject<boolean>;

    constructor() {
        this.boolSubject = new Subject<boolean>();
        this.myBool$ = this.boolSubject.asObservable();
    }

    set myBool(newValue) {
      this._myBool = newValue;
      this.boolSubject.next(newValue);
    }
}
13