【问题标题】:Why factory resolver does work only one time?为什么工厂解析器只能工作一次?
【发布时间】:2021-01-15 02:30:05
【问题描述】:

我有一个定义了工厂的对话框模块:

@NgModule({
    declarations: [...components, ...directives],
    imports: [...modules],
    providers: [
        CustomBlockService,
        {
            provide: DocumentCustomBlock,
            useFactory: (httpClient: HttpClient, customBlockService: CustomBlockService) => {
                console.log(customBlockService.type);
                switch (customBlockService.type) {
                    case 'doc_num_date_block':
                        return new DocNumDateBlock(
                            httpClient,
                            customBlockService,
                            new DocNumDateBlockFormGroup(createFormControls(customBlockService.value)),
                        );
                    case 'find_unom_by_address_block':
                        return new FindUnomAddressBlock(
                            httpClient,
                            customBlockService,
                            new FindUnomAddressBlockFormGroup(createFormControls(customBlockService.value)),
                        );
                    default:
                        throw 'Error type custom block!';
                }
            },
            deps: [HttpClient, CustomBlockService],
        },
    ],
    entryComponents: [...components],
})
export class DialogLoadDocumentModule {}

对话框的这个模块从父组件中抽出,在窗口打开之前,选定的块被添加到CustomBlockService服务中:

public setDocument(): void {
   this.customBlockService.block = this.block;
}

第一次工作时,我在对话框中看到DocumentCustomBlock 提供程序中的选定数据this.customBlockService.block = this.block;

当窗口关闭并使用新的this.customBlockService.block = this.block; 重新打开时,我会在服务中看到旧数据。

那么,如果要做控制台:

useFactory: (httpClient: HttpClient, customBlockService: CustomBlockService) => {
         console.log(customBlockService.type);
});

我注意到控制台仅在第一次工作,然后不工作,尽管 CustomBlockService 中的属性已更改。

我已经尝试添加这个:

  { provide: CustomBlockService, useClass: CustomBlockService },

每次加载模块时在同一个模块中创建一个新实例CustomBlockService。但是没有成功。

【问题讨论】:

    标签: angular


    【解决方案1】:

    服务是在这个模块的级别声明的,并且模块不会被多次加载。如果要删除服务类,只需将其设置为对话框最顶层组件的提供者即可。这样,当组件离开 dom 时,服务也会随之消亡。

    附:确保通过 ngOnDestroy 清理服务中的所有订阅。

    This StackOverflow Post 有一个关于服务生命周期的不错答案,可能是一个很好的参考。

    【讨论】:

    • 您能否分享一个如何修改我的提供程序或创建新提供程序的示例?
    • Provider 数组是一个可以赋予模块和组件的属性。当您将它提供给组件时,它将导致服务在创建/实例化组件时激活,并在它死亡时死亡。模块的行为是相同的,但模块不只是“消失”。如果您希望多个模块或组件中的相同服务具有不同的数据,或者您希望服务数据在组件被销毁之前一直存在,则在较低级别提供提供程序数组可能很有用。
    • 您的问题与提供程序数组本身(您定义工厂的位置)关系不大,而与您定义服务的位置(哪个提供程序数组)有关。还值得注意的是,如果您的服务在顶部有 `injectable { providedIn: 'root'},那么它将在 'app-module' 中有效地定义。如果你有这个,把它改成'Injectable()'
    • 我想我明白了。您希望数据从父组件派生,然后子组件使用它。我会质疑为什么不只是将输入参数传递给组件,但是您可以做一些事情,只要您执行显示模态的逻辑,您就可以执行类似“myService.initialize('mydata1', foo, bar, etc... )" 并做任何你想做的事情来按预期设置服务数据。
    • 此时您可以通过 injectable ... providedIn: root ... 将服务置于根级别,只需执行特定的服务调用来管理服务中的数据
    猜你喜欢
    • 2019-10-08
    • 2021-03-30
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 2012-03-09
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多