如何在我的.forRoot()中初始化angular中的第三方模块

时间:2018-12-07 18:50:47

标签: angular toastr angular-toastr

我正在使用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 个答案:

答案 0 :(得分:1)

通过providers导出通知服务的根模块应该是在ToastrModule.forRoot()声明中使用imports的唯一模块。

forRoot()调用是一个约定,不是框架强制执行的约定。其他人在定义他们的NgModules时不应该调用它,如果已经被更高版本调用了。

As mentioned in the Angular documentation:

  

仅在根应用程序模块.forRoot()中调用并导入AppModule结果。将其导入任何其他模块(尤其是在延迟加载的模块中)与意图相反,并且可能会产生运行时错误。

     

...

     

forRoot()forChild()是分别在根模块和功能模块中配置服务的方法的常规名称。

如果您对ToastrModule的全局配置从未改变,那么按照您在代码段中所质疑的方式进行操作,我认为这没有错。

但是,如果配置可能因ToolsCoreModule的使用者而异,则不应为每个不同的配置调用forRoot(),因为按照惯例这是错误的。在这种情况下,您可以考虑围绕toast调用的第三个参数创建包装程序,以传递通用配置(例如this.toastrService.error(msg, title, config))。

答案 1 :(得分:0)

正如@migh 提到的,forRoot() 应该只由 AppModule 调用,但是 forRoot() 提供程序中的嵌套 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