Как установить config (или useValue) для импортируемых модулей из компонента? - PullRequest
0 голосов
/ 16 января 2019

Мы хорошо знаем, что существуют различные способы настройки конфигурации для импортируемых модулей. У нас есть '.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 {}

Однако, если вы хотите установить config / useValue динамически (например, на странице настроек), мы должны изменить ее из компонента. Теперь я проверил это с помощью следующего кода, написанного непосредственно в 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() {
  }
}

К сожалению, изменение не отразилось на компонентах, использующих ng2-currency-mask, и конфигурация, установленная из AppModule (с параметром "Module $" в качестве prefix), по-прежнему работает.

Как успешно переопределить / установить конфигурацию модуля из компонента?

UPDATE:

Я пытался использовать ReflectiveInjector resolve и fromResolvedProviders методы, которые также не работают:

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

И использование Static Injector не работает:

Injector.create(
[
    { 
        provide: CURRENCY_MASK_CONFIG, 
        useValue: ng2CurrencyMaskConfig 
    }
], 
this.injector);

Примечание стороны: Мне хорошо известно альтернативное решение для этого конкретного модуля (CurrencyMaskModule), где мы на самом деле можем просто сделать провайдера с изменяемым свойством, которое будет содержать значение CurrencyMaskConfig. Но это заставит меня изменить все поля ввода, добавив атрибут options ко всем полям ввода, используя директиву currencyMask. Другими словами, я буду вставлять что-то вроде [options]="myConfigProvider.currencyMaskConfig" во все входные данные, которые в этом нуждаются. Я надеюсь увидеть лучший / более элегантный способ сделать это.

...