web-dev-qa-db-ja.com

依存性注入トークンの値を更新する方法

角度依存性注入を使用すると、サービスクラスの代わりにトークンを使用して文字列、関数、またはオブジェクトを注入できます。

私はそれを私のモジュールで次のように宣言します:

providers: [{ provide: MyValueToken, useValue: 'my title value'}]

そして私はそれを次のように使用します:

constructor(@Inject(MyValueToken) my_value: string) {
  this.title = my_value;
}

ただし、コンポーネントから値を更新し、新しい値を取得するたびに他のコンポーネントに取得させるにはどうすればよいですか?つまり、BehaviorSubjectのようなものを使用して値を送受信する機能をシミュレートしたいと思います。

これが不可能な場合、静的データのみを提供する場合、これらのインジェクショントークン値はどのように使用されますか。代わりに、コンポーネントで静的値を宣言して直接使用できます。

10
Hamed Baatour

不変のプリミティブの代わりに、BehaviorSubjectを使用して、一方のコンポーネントでそれにアクセスして更新し、もう一方のコンポーネントでサブスクライブすることができます。

providers: [{ provide: MyValueToken, useValue: new BehaviorSubject('')}]

// consumer
constructor(@Inject(MyValueToken) my_value: BehaviorSubject) {
  my_value.subscribe((my_value)=>this.title = my_value);
}

// producer
constructor(@Inject(MyValueToken) my_value: BehaviorSubject) {
  my_value.next('my title value');
}
10
Maxim Koretskyi

BehaviorSubjectを使用したくない場合は、代わりにゲッターとセッターを備えた単純なクラスを提供できます。

class MyValue {

  get value(): string {
    return this._value;   
  }

  set value(val: string) {
   this._value = val;
  }
  private _value = '';

}

const MY_VALUE_TOKEN = new InjectionToken<MyValue>('MY_VALUE_TOKEN ');

// Provide class in either module or component providers array.
providers: [
  { provide: MY_VALUE_TOKEN , useClass: MyValue },
]

class MyComponent {

  // Inject in component constructor
  constructor(
    @Inject(MY_VALUE_TOKEN) private _myValue: MyValue,
  ) {

    // Access current value
    console.log(this._myValue.value);

    // Set new value
    this._myValue.value = 'new value';
  }

}

1
Luke Gatchell

ウィザードに加えて:

すべてのコンシューマーがBehaviourSubjectの独自のインスタンスを必要とするユースケースがある場合。 (私はたまたまこのユースケースにいます)。必ずファクトリを定義してください。

const myFactory = () => { return new BehaviorSubject<string>('') };

providers: [
    { provide: MyValueToken, useFactory: myFactory }
]

// Then, as proposed in the top-answer.

// consumer
constructor(@Inject(MyValueToken) my_value: BehaviorSubject) {
  my_value.subscribe((my_value)=>this.title = my_value);
}

// producer
constructor(@Inject(MyValueToken) my_value: BehaviorSubject) {
  my_value.next('my title value');
}
1
Andre Elrico