16

Angular 依赖注入允许您使用令牌而不是服务类来注入字符串、函数或对象。

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

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

我像这样使用它:

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

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

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

4

4 回答 4

19

您可以使用 a 代替不可变的原语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');
}
于 2017-10-15T12:54:44.040 回答
6

除了向导:

如果您有一个用例,其中每个消费者都需要自己的 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');
}

于 2019-08-20T13:05:42.730 回答
4

如果您不想使用 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';
  }

}

于 2019-11-08T15:20:13.680 回答
0

关于为什么...

由于您还想知道为什么要注入静态结构,Angular Material 经常这样做以向组件提供配置。

例如。对于芯片控制

@NgModule({
  providers: [
    {
      provide: MAT_CHIPS_DEFAULT_OPTIONS,
      useValue: {
        separatorKeyCodes: [ENTER, COMMA]
      }
    }
  ]
})

无需了解这些数据代表什么,只需意识到您正在注入一个MAT_CHIPS_DEFAULT_OPTIONS有价值的代币{ separatorKeyCodes: [ENTER, COMMA] }

这将从您的 AppModule 或您定义的任何模块或组件继承 - 就像任何其他可注入服务一样。这同样可以在您的@Component定义@Directive中为单个组件(及其子组件)提供配置。

当然,当您的应用程序中的不同模块或组件需要不同的配置时,您将其注入那里,并且只有子组件会继承它。

老实说,这样做似乎很痛苦,而不仅仅是在组件上设置一个值,但这就是它适用于许多 Angular Material 控件的方式。当然,好处是你只做一次,一切都会继承它。

于 2021-06-30T02:22:55.913 回答