如何为从组件导入的模块设置config(或useValue)?

Col*_*rus 5 dependency-injection typescript angular-module angular angular-dependency-injection

我们很清楚,有多种方法可以为导入的模块设置config。我们有“ .forRoot()”,“ useValue”,“ useClass”,这些将在导入模块中使用。

例如,我们要使用ng2-currency-mask。直接从文档中的示例用法中,我们可以CurrencyMaskModule通过在导入模块(在本例中为AppModule)中进行设置来进行配置:

export const CustomCurrencyMaskConfig: CurrencyMaskConfig = {
    align: "right",
    allowNegative: true,
    decimal: ",",
    precision: 2,
    prefix: "Module$ ",
    suffix: "",
    thousands: "."
};

@NgModule({
    imports: [
        ...
        CurrencyMaskModule
    ],
    declarations: [...],
    providers: [
        { provide: CURRENCY_MASK_CONFIG, useValue: CustomCurrencyMaskConfig }
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

但是,如果要useValue动态设置config / (例如,“设置”页面),则必须在组件内部进行更改。现在,我使用以下直接在中编写的代码进行了测试AppComponent

import { Component, OnInit, Inject } from '@angular/core';
import { CURRENCY_MASK_CONFIG, CurrencyMaskConfig } from 'ng2-currency-mask/src/currency-mask.config';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'Testing Config App';

  constructor(
    @Inject(CURRENCY_MASK_CONFIG) ng2CurrencyMaskConfig: CurrencyMaskConfig,
  ) {
    // test
    ng2CurrencyMaskConfig =  {
      align: 'right',
      allowNegative: false,
      decimal: '.',
      precision: 5,
      prefix: 'Component$$$ ',
      suffix: '',
      thousands: ','
    };
  }

  ngOnInit() {
  }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,所做的更改并未反映到所使用的组件上,ng2-currency-mask并且的配置集AppModule(“ Module $”为prefix)仍然有效。

如何从组件内部成功覆盖/设置模块的配置?

更新:

我尝试使用ReflectiveInjectorresolvefromResolvedProviders方法也无法正常工作:

import { Component, OnInit, ReflectiveInjector, Injector } from '@angular/core';
import { CURRENCY_MASK_CONFIG, CurrencyMaskConfig } from 'ng2-currency-mask/src/currency-mask.config';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'Testing Config App';

  constructor(
    private injector: Injector,
  ) {
  }

  ngOnInit() {
     // test
     const ng2CurrencyMaskConfig: CurrencyMaskConfig =  {
      align: 'right',
      allowNegative: false,
      decimal: '.',
      precision: 3,
      prefix: 'TESTR$ ',
      suffix: '',
      thousands: ','
    };

    const providers = ReflectiveInjector.resolve([{ provide: CURRENCY_MASK_CONFIG, useValue: ng2CurrencyMaskConfig }]);
    ReflectiveInjector.fromResolvedProviders(providers, this.injector);
  }
}
Run Code Online (Sandbox Code Playgroud)

并且使用静态Injector不起作用:

Injector.create(
[
    { 
        provide: CURRENCY_MASK_CONFIG, 
        useValue: ng2CurrencyMaskConfig 
    }
], 
this.injector);
Run Code Online (Sandbox Code Playgroud)

旁注:我很清楚这个特定模块(CurrencyMaskModule)的替代解决方案,在该方案中,我们实际上可以使提供程序具有可变的属性来保存该CurrencyMaskConfig值。但这将使我不得不更改所有输入字段,以options使用currencyMask指令将属性添加到所有输入字段。换句话说,我将[options]="myConfigProvider.currencyMaskConfig"在所有需要它的输入中插入类似内容。我希望看到一种更好/更优雅的方法。