Конфигурируемые модули Angular

Используется шаблон forRoot (метод может называться как угодно, но принято называть forRoot). Он принимает в качестве параметра объект конфигурации модуля.

/**
 * Интерфейс конфигурации модуля
 */
interface UserServiceConfig {
  userName: string;
}

const USER_CONFIG_TOKEN = new InjectionToken<UserServiceConfig>('unique.string.for.config');

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

Конфигурируемый модулем сервис user.service.ts

@Injectable()
export class UserService {
  private _userName = 'Sherlock Holmes';

  constructor(@Inject(USER_CONFIG_TOKEN) config: UserServiceConfig) {
    this._userName = config.userName;
  }

  hello() {
    return this._userName + ' say hello!';
  }
}

Конфигурируемый модуль greeting.module.ts

@NgModule({
  imports:      [ CommonModule ],
  declarations: [ GreetingComponent ],
  exports:      [ GreetingComponent ]
})
export class GreetingModule {
  // необязательный шаблон для уникальности импорта модуля
  constructor (@Optional() @SkipSelf() parentModule: GreetingModule) {
    if (parentModule) {
      throw new Error(
        'GreetingModule is already loaded. Import it in the AppModule only');
    }
  }

  /**
   * Метод который будет вызван когда модуль импортиться в root модуле
   * @param config - конфигурация, в данном случае задается имя пользователя
   */
  static forRoot(config: UserServiceConfig): ModuleWithProviders {
    return {
      ngModule: GreetingModule,
      providers: [
        { provide: USER_CONFIG_TOKEN, useValue: config } // <=== провайдер
        UserService,
      ]
    };
  }
}

Использование

app.module.ts

@NgModule({
  imports: [
    BrowserModule,
    GreetingModule.forRoot({ userName: 'Spider Man' }),
  ],
  declarations: [
    AppComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Похожие записи

Angular dependency injection

Определение Provider (useClass, useValue, useFactory ), Injector. Декоратор @Inject, ключ multi: true

13 ноября 2018 г. в Angular

@Attribute() декоратор

Аналогично @Input() позволяет получить значение атрибута с хоста компонента/директивы, но не отслеживает дальнейшее изменение атрибута.

14 сентября 2019 г. в Angular

Об subscribe() vs async

О предпочтительности использования async pipe. При OnPush стратегии не требуется вызывать markForCheck() внутри подписки +решение с несколькими | async pipes развёрнутых в одну переменную (внутри шаблона).

05 января 2019 г. в Angular

Angular Resolver

Resolver гарантированно получает асинхронные данные до создания компонента исходя из параметров маршрута.

TS. Event bus

Создаётся providedIn: 'root' сервис событий. Затем отправляются события на шину, и если какой-либо слушатель подписан на эти события, он получает уведомления.