Как я могу инициализировать сторонний модуль в моем.forRoot() в угловых
Я строю внутреннюю библиотеку для наших проектов, используя Angular 6+. Я использую .forRoot()
подход к регистрации глобальных услуг, как это задокументировано.
Моя библиотека будет использовать ngx-toastr
предоставлять уведомления. Поскольку я не хочу, чтобы каждый проект имел дело со всеми вариантами ngx-toastr
Я абстрагирую большую часть этого за notifications
оказание услуг.
Путь ngx-toastr
работает, вы можете установить глобальные параметры, передавая эти глобальные параметры ToastrModule.forRoot()
,
как я могу настроить ToastrModule
как часть моей forRoot()
?
Это явно плохая идея добавить любой код внутри .forRoot()
, но это правильный способ инициализировать его прямо в моем @NgModule()
? как это:
@NgModule({
imports: [ToastrModule.forRoot(/* options go here? */)],
declarations: [],
exports: []
})
export class ToolsCoreModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: ToolsCoreModule,
providers: [],
};
}
}
Как это будет взаимодействовать, если кто-то из команды решит также позвонить? ToastrModule.forRoot()
в рамках собственной инициализации модуля?
2 ответа
Как упоминалось в @migh, должен вызываться только, но вложенный в
forRoot()
провайдер по-прежнему вызывается
AppModule
не так ли?
Итак, вы можете сделать следующее
@NgModule({
imports: [],
declarations: [],
exports: [ToastrModule]
})
export class ToolsCoreModule {
static forRoot(/* your options */): ModuleWithProviders {
return {
ngModule: ToolsCoreModule,
providers: [...ToastrModule.forRoot(/* toastr options */).providers],
};
}
}
Как это будет взаимодействовать, если кто-то в команде решит также позвонить
ToastrModule.forRoot()
в рамках собственной инициализации модуля?
Вы можете получить ошибку во время выполнения или странное поведение.
Чтобы избежать «странного поведения», вам также следует добавить в свой модуль этот шаблон, предотвращающий двойную регистрацию:
constructor(@Optional() @SkipSelf() parentModule?: ToolsCoreModule)
{
if (parentModule)
{
throw new Error(
"ToolsCoreModule is already loaded. Import it in the AppModule only!");
}
}
Этот шаблон взят из официальной документации:https://angular.io/guide/singleton-services#prevent-reimport-of-the-greetingmodule
Корневой модуль, который экспортирует ваш сервис уведомлений через providers
должен быть единственным, который использует ToastrModule.forRoot()
в imports
декларация.
forRoot()
Вызов - это соглашение, а не что-то, что поддерживается платформой. Другие не должны вызывать это при определении своих NgModules, если он уже был вызван выше.
Как упомянуто в угловой документации:
Только позвонить и импортировать
.forRoot()
результат в модуле корневого приложения,AppModule
, Импортирование его в любой другой модуль, особенно в модуль с отложенной загрузкой, противоречит цели и может привести к ошибке времени выполнения....
forRoot()
а такжеforChild()
являются условными именами методов, которые настраивают службы в корневых и функциональных модулях соответственно.
Если ваша глобальная конфигурация для ToastrModule
никогда не меняется, я не думаю, что есть что-то плохое в том, как вы задали вопрос в своем фрагменте.
Однако, если конфигурация может измениться в зависимости от потребителей ToolsCoreModule
ты не должен звонить forRoot()
для каждой отдельной конфигурации, поскольку это неправильно по соглашению. В этом случае вы можете рассмотреть возможность создания оберток вокруг третьего аргумента вызовов toast для передачи общей конфигурации (например, this.toastrService.error(msg, title, config)
).