实现动态模块时,@NgModule静态forRoot widget.module.ts shell.component.ts shell.component.html widget.module.ts shell.component.ts

我在@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 方法中?

funnydoing 回答:实现动态模块时,@NgModule静态forRoot widget.module.ts shell.component.ts shell.component.html widget.module.ts shell.component.ts

探索了一段时间之后,我想我已经找到了解决方案。

widget.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],parentInjector);
                })
        })

}

shell.component.html

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

如您所见,如果您具有依赖性(由模块消费者提供),将会在该模块的组件中跨使用,并且您使用compileModuleAndAllComponentsAsync方法,则这些组件将无法访问该依赖项,除非手动创建另一个进样器。

这是因为,正如您通过方法名称所知,这些组件已经被编译,因此,除了在显式中定义的那些依赖项之外,您无法动态添加其他依赖项。模块。


如果模块内的组件依赖于所提供的依赖关系,则可以通过仅首先编译模块(compileModuleAsync)然后分别编译每个组件来实现此目的(这听起来很繁琐,但是我可以向您保证您将喜欢使用此东西)。这样,他们将能够在运行时注入任何动态提供的依赖项,事件。

widget.module.ts

@NgModule({
  imports: [
    CommonModule,// RouterModule.forChild([{ path: '',component: 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,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组件数组中,以便您可以使用{{1 }}。

Here is a StackBlitz example

本文链接:https://www.f2er.com/3165848.html

大家都在问