如何更新依赖注入令牌值

Ham*_*our 10 typescript angular-services angular-decorator angular angular-di

角度依赖注入允许您使用令牌而不是服务类注入字符串,函数或对象.

我在我的模块中声明它是这样的:

providers: [{ provide: MyValueToken, useValue: 'my title value'}]
Run Code Online (Sandbox Code Playgroud)

我这样使用它:

constructor(@Inject(MyValueToken) my_value: string) {
  this.title = my_value;
}
Run Code Online (Sandbox Code Playgroud)

但是,如何更新组件中的值并让其他组件每次都获得新值?换句话说,我想模拟使用类似a BehaviorSubject来发射和接收值的功能.

如果这不可能,那么如果它们仅提供静态数据,那么这些注入令牌值的用途是什么,而我可以简单地在我的组件中声明静态值并直接使用它.

Max*_*kyi 9

除了使用不可变的原语,您可以使用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');
}
Run Code Online (Sandbox Code Playgroud)

  • @HamedBaatour是的。但是,如果多个组件使用的值没有机会被更改,则可以安全地跳过DI部分并将其设为const。同样,它总是取决于。“窗口”永远不会改变,但出于测试原因,将其保留为提供程序是有意义的,例如[that](/sf/answers/3214863081/)。 (2认同)

小智 6

如果您不想使用 a BehaviorSubject,您可以提供一个带有 getter 和 setter 的简单类。

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';
  }

}

Run Code Online (Sandbox Code Playgroud)

  • 这不会只更新注入变量的“本地”副本吗?我相信OP正在询问如何在全球范围内应用这一变化 (2认同)

And*_*ico 5

除了精灵:

如果您有一个用例,其中每个使用者都需要自己的 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');
}
Run Code Online (Sandbox Code Playgroud)