简体   繁体   English

调用 forRoot 时,Angular 延迟加载不起作用

[英]Angular lazy load does not work when invoking forRoot

I have a lazy load module which needs to expose providers, so I am using the forRoot convention and returning the following code:我有一个需要公开提供程序的延迟加载模块,所以我使用了forRoot约定并返回以下代码:

@NgModule({
  imports: [RouterModule.forChild([
    {path: "", component: LazyComponent},
  ])],
  declarations: [LazyComponent],
})
export class LazyModule {
  static forRoot() {
    return {
      ngModule: LazyModule,
      providers: [provider]
    };
  }
}

The problem is when I invoke the forRoot in my app module the lazy load does not work anymore.问题是当我在我的应用程序模块中调用 forRoot 时,延迟加载不再起作用。 ( I don't see the separate chunk in my console ) (我在控制台中没有看到单独的块)

@NgModule({
  declarations: [
    AppComponent,
    HelloComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    LazyModule.forRoot() <======== this stops the lazy load module
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

From what I learned it should only make the providers singleton, why it does not work?据我所知,它应该只使提供者成为单例,为什么它不起作用?

As of right now, it's not possible to execute a forRoot (or any other configuration static method of this sort) in a module that will load lazily.就目前而言,无法在延迟加载的模块中执行forRoot (或任何其他此类配置静态方法)。 The problem here is that such a method returns a ModuleWithProviders while loadChildren requires a NgModuleFactory .这里的问题是这样的方法返回一个ModuleWithProviders而 loadChildren 需要一个NgModuleFactory

When you import a LazyModule in your AppModule imports array it is not "lazy" anymore.当您在AppModule导入数组中导入LazyModule ,它不再“懒惰”了。 A lazy module should only be referenced in a dedicated RoutingModule .一个惰性模块应该只在一个专用的RoutingModule被引用。

So if I understood you correctly you would like to share a Service between your LazyModules?因此,如果我理解正确,您想在您的 LazyModules 之间共享服务吗?

If so remove LazyModule from AppModule and create a SharedModule and move your Service you like to share inside the providers array in SharedModule.如果是这样,从AppModule删除LazyModule并创建一个 SharedModule 并移动您喜欢在 SharedModule 中的providers数组中共享的providers Import SharedModule in your AppModule with forRoot and import your SharedModule without forRoot in your LazyModules进口SharedModule在你AppModuleforRoot并导入SharedModule没有forRoot在LazyModules

I faced a similar issue where I had to lazy load a module with some configurations.我遇到了类似的问题,我不得不延迟加载具有某些配置的模块。 So, I came up with this temporary fix.所以,我想出了这个临时解决办法。

Lazy Module懒惰模块

    @NgModule({
          imports: [
             RouterModule.forChild([
              {path: "", component: LazyComponent},
             ])],
          declarations: [LazyComponent],
    })
    export class LazyModule {
       // considering the function only handle providers 
       static setDynamicProviders(provider?: any) {
            if(LazyModule && LazyModule.__annotations__ && LazyModule.__annotations__[0]){
            LazyModule.__annotations__[0].providers.push(provider);               
          }
            return LazyModule;
       }
   }

Parent Module父模块

const someService = {
  provide: 'SOME_TOKEN',
  useFactory: (dependecy1) => (//dome something with dependency1)
  deps: [SOME_DEPENDENCY_TOKEN]
}

@NgModule({
 imports: [
    RouterModule.forRoot([
        path: 'lazy',
        loadChildren: ()=>(import('*your path to lazy module*').then(ref => ref.LazyModule.setDynamicProvider(someService)))
    ])
  ]
})

So, I am just modifying the annotations created by @NgModule Decorator.所以,我只是修改@NgModule Decorator 创建的注释 At this stage, Angular does not support lazy loading with static methods that return ModuleWithProviders .在这个阶段,Angular 不支持使用返回ModuleWithProviders静态方法的延迟加载。

Try below code when we define a module is Lazy RouterModule.forChild:当我们定义一个模块是 Lazy RouterModule.forChild 时,试试下面的代码:

@NgModule({
  imports: [RouterModule.forChild([
    {path: "", component: LazyComponent},
  ])],
  declarations: [LazyComponent],
})
export class LazyModule { }

But when we load in the parent module, try the below code:但是当我们加载父模块时,请尝试以下代码:

@NgModule({
  declarations: [
    AppComponent,
    HelloComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    RouterModule.forRoot([
     {
         path: '',
         loadChildren: './layout/layout.module#LayoutModule',
         canActivate: [AuthGuard]
     }
    ]) <======== right way to load lazy module
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

Note: FullPath is like './moduleFolder/lazy.module#LayoutModule'注意:FullPath 就像 './moduleFolder/lazy.module#LayoutModule'

LayoutModule is your exported Module Name LayoutModule 是您导出的模块名称

Please let me know请让我知道

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM