簡體   English   中英

@NgModule static forRoot 實現動態模塊時

[英]@NgModule static forRoot when implementing dynamic modules

我在@NgModule 中有這段代碼:

@NgModule({
 declarations: [
   AppComponent,
   DashboardComponent
 ],
 imports: [
   BrowserModule,
   BrowserAnimationsModule,
   ClarityModule,
   RouterModule.forRoot([
     {
       path: '', redirectTo: 'dashboard', pathMatch: 'full'
     },
     {
       path: 'dashboard', component: DashboardComponent
     },
   ], {useHash: true}),
   LibraryTestModule.forRoot(ServicetestService),
   HttpModule
 ],

如果您可以看到我正在將 ServicetestService 注入 LibraryTestModule。

但在我的情況下,我使用下面的代碼使用 system.js 動態加載這個模塊:

// now, import the new module
    return SystemJS.import(`${url}`).then((module) => {
        console.log(module);

        return SystemJS.import(`${url}`).then((module) => {
            console.log(module);
            return this.compiler.compileModuleAndAllComponentsAsync(module[`${moduleInfo.moduleName}`]).then(compiled => {
                console.log(compiled);
                return module;
            });
        });
    });

現在有什么方法可以在動態加載模塊時將 ServiceTestService 注入到compileModuleAndAllComponentsAsync方法中?

經過一段時間的探索,我想我已經找到了解決方案。

小部件.module.ts

export const DYNAMIC_CONFIG = new InjectionToken('DYNAMIC_CONFIG');

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [WidgetComponent],
  entryComponents: [WidgetComponent]

  providers: [
  ]
})
export class WidgetModule { }

現在讓我們假設您正在將此模塊動態加載到 shell 組件中:

shell.component.ts

ngOnInit () {
    const parentInjector = Injector.create({
        providers: [
            { provide: DYNAMIC_CONFIG, useValue: { message: 'CUSTOM VALUE PROVIDED BY THE CONSUME!' } }
        ],
        parent: this.inj
    });

    import('./widget/widget.module.ts')
        .then(m => {
            this.compiler.compileModuleAndAllComponentsAsync(m.WidgetModule)
                .then(moduleWithCompFactories => {
                    const module = moduleWithCompFactories.ngModuleFactory.create(parentInjector);

                    /**
                     * Adding the components from the lazy-loaded module
                     * into the current view
                     */
                    this.vc.createComponent(moduleWithCompFactories.componentFactories[0], 0, parentInjector);
                })
        })

}

shell.component.html

<ng-container #vc></ng-container>

如您所見,如果您的依賴項(模塊使用者提供)將用於作為該模塊一部分組件並且您使用compileModuleAndAllComponentsAsync方法,則組件將無法訪問該依賴項,除非手動創建另一個注入器。

這是因為,從方法的名稱可以看出,組件已經被編譯,所以除了在模塊中明確定義的那些之外,您不能動態添加其他依賴項。


如果模塊內的組件依賴於提供的依賴項,您可以通過首先編譯模塊( compileModuleAsync )然后單獨編譯每個組件來實現(這聽起來可能很乏味,但我可以向您保證,您會喜歡使用它東西)。 這樣,他們將能夠在運行時注入任何動態提供的依賴項和事件。

小部件.module.ts

@NgModule({
  imports: [
    CommonModule,
    // RouterModule.forChild([{ path: '', component: WidgetComponent }])
  ],
  declarations: [WidgetComponent],

  // No need to use this when using `compileModuleAndAllComponentsAsync`
  entryComponents: [WidgetComponent],
  providers: [
    {
      provide: 'widgets',
      useValue: [
        {
          name: 'widget1',
          component: WidgetComponent,
        },
      ],
    }
  ]
})
export class WidgetModule { }

shell.component.ts

ngOnInit () {
    const parentInjector = Injector.create({
        providers: [
            { provide: DYNAMIC_CONFIG, useValue: { message: 'CUSTOM VALUE PROVIDED BY THE CONSUME!' } }
        ],
        parent: this.inj
    });

    import('./widget/widget.module.ts')
        .then(m => {
            this.compiler.compileModuleAsync(m.WidgetModule)
                .then(factory => {
                    const module = factory.create(parentInjector);

                    const [firstWidget] = module.injector.get('widgets');

                    const componentFactory = module.componentFactoryResolver.resolveComponentFactory(firstWidget.component);

                    this.vc.createComponent(componentFactory);
                });
        })

}

現在,每次您想向模塊添加另一個組件時,請確保將其添加到entryComponents組件數組,以便您可以使用module.injector.get()檢索它們。

這是一個 StackBlitz示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM