0

我正在为我们的项目构建一个内部库,使用 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()如果团队中的某个人决定在他们自己的模块初始化中也调用,这将如何交互?

4

2 回答 2

1

正如@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

于 2021-07-05T15:23:37.213 回答
1

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

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

如 Angular 文档中所述:

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

...

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

如果您的全局配置ToastrModule永远不会改变,我认为按照您在代码段中质疑的方式进行操作没有任何问题。

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

于 2018-12-08T01:22:56.420 回答