Конфигурация значений по умолчанию с использованием forRoot работает в Dev, но не в Prod (Aot)

Следующий код отлично работает в режиме Dev, но не в режиме Prod:

Модуль

export class SpinnerModule {
  static forRoot(config?: SpinnerConfig): ModuleWithProviders {
    return {
      ngModule: SpinnerModule,
      providers: [SpinnerService, { provide: SpinnerConfigToken, useValue: { ...DEFAULT_CONFIG, ...config } }]
    };
  }
}

Токен конфигурации

export const SpinnerConfigToken = new InjectionToken<SpinnerConfig>('SPINNER CONFIG TOKEN');

Модель

// Project imports
import { Color, SpinnerAnimation } from '../../../models';

export interface SpinnerConfig {
  label?: string;
  color?: Color;
  animation?: SpinnerAnimation;
}

export const DEFAULT_CONFIG: SpinnerConfig = {
  label: '',
  color: Color.Blue,
  animation: SpinnerAnimation.DoubleBounce
};

Компонент

export class SpinnerComponent implements OnInit {
  @Input() isLoading: boolean;
  @Input() label: string;
  @Input() color: Color;
  @Input() animation: SpinnerAnimation;

  isFullScreen: boolean;
  spinnerAnimation: typeof SpinnerAnimation;

  constructor(@Inject(SpinnerConfigToken) private config: SpinnerConfig) {
    this.spinnerAnimation = SpinnerAnimation;
  }

  ngOnInit(): void {
    this.isLoading = !!this.isLoading;
    this.color = this.color || this.config.color;
    this.label = this.label || this.config.label;
    this.animation = this.animation || this.config.animation;

Модуль приложения

@NgModule({
  imports: [
    ...
    SpinnerModule.forRoot({
      label: 'Loading, please wait ...'
    })
  ],
 ...
})
export class AppModule {}

Я хотел бы объединить данную конфигурацию с тем, что я установил в качестве значений по умолчанию. то, что я сделал, отлично работает в Dev, но в Prod у меня нет ошибок, но значения не определены, похоже, что оператор распространения для слияния двух объектов не работает,

Большое спасибо.


person Youness Houdass    schedule 17.01.2020    source источник
comment
Я смог заставить его работать с помощью useFactory, но я считаю, что это так много дополнительного кода для небольшой функциональности, есть идеи, как заставить его работать только с useValue или, может быть, небольшой трюк в том же контексте?   -  person Youness Houdass    schedule 17.01.2020


Ответы (2)


Вы должны создать функцию, чтобы работать с сборкой aot.

export function DefaultConfig(config: HttpClient) {
  return ({ ...DEFAULT_CONFIG, ...config })
}

а также:

providers: [SpinnerService, { provide: SpinnerConfigToken, useFactory: DefaultConfig }]
person Marcel Hoekstra    schedule 17.01.2020

Спасибо, Марсель, я смог решить эту проблему с помощью useFactory, как я уже сказал в комментариях, например:

providers: [
   ToastService,
   { provide: ToastConfigToken, useValue: config },
   { provide: ToastConfigService, useFactory: defaultConfig, deps: [ToastConfigToken] }
]

export function defaultConfig(config: ToastConfig): any {
  return ({ ...DEFAULT_CONFIG, ...config })
}

Но я бы хотел что-то более простое, чем использование двух useValue и useFactory для очень простой функциональности.

person Youness Houdass    schedule 17.01.2020