【问题标题】:Angular lazy load does not work when invoking forRoot调用 forRoot 时角度延迟加载不起作用
【发布时间】:2018-07-14 02:03:58
【问题描述】:

我有一个需要公开提供程序的延迟加载模块,因此我使用forRoot 约定并返回以下代码:

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

问题是当我在我的应用程序模块中调用 forRoot 时,延迟加载不再起作用。 (我在控制台中没有看到单独的块)

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

据我所知,它应该只使提供者单例,为什么它不起作用?

【问题讨论】:

  • 如果你在 Eager 模块中导入 LazyLoad 模块,那么 webpack 不会为它创建块
  • 所以你的意思是我不能同时延迟加载我的模块和使用 forRoot?
  • 您可以创建仅包含提供程序的单独模块并导入它

标签: javascript angular


【解决方案1】:

我遇到了类似的问题,我不得不延迟加载具有某些配置的模块。所以,我想出了这个临时解决方案。

懒惰的模块

    @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;
       }
   }

父模块

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)))
    ])
  ]
})

所以,我只是在修改@NgModuleDecorator 创建的注释。在这个阶段,Angular 不支持使用返回 ModuleWithProviders 的静态方法进行延迟加载。

【讨论】:

  • 如果是第 13 版,您可以将提供者推送为LazyModule['ɵinj'].providers.push(provider)
【解决方案2】:

目前,无法在延迟加载的模块中执行forRoot(或任何其他此类配置静态方法)。这里的问题是这样的方法返回一个ModuleWithProviders,而loadChildren 需要一个NgModuleFactory

【讨论】:

    【解决方案3】:

    当我们定义一个模块是 Lazy RouterModule.forChild 时试试下面的代码:

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

    但是当我们在父模块中加载时,试试下面的代码:

    @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 {
    }
    

    注意:FullPath 类似于 './moduleFolder/lazy.module#LayoutModule'

    LayoutModule 是您导出的模块名称

    请告诉我

    【讨论】:

    • 这没有回答他的问题。这里提到的 forRoot 在哪里?
    【解决方案4】:

    当您在 AppModule 导入数组中导入 LazyModule 时,它不再“懒惰”了。只能在专用的RoutingModule 中引用惰性模块。

    如果我理解正确的话,您想在您的 LazyModules 之间共享服务吗?

    如果是这样,请从 AppModule 中删除 LazyModule 并创建一个 SharedModule 并将您想要共享的服务移动到 SharedModule 中的 providers 数组中。在您的 AppModule 中导入 SharedModule 和 forRoot 并在您的 LazyModules 中导入您的 SharedModule 而不使用 forRoot

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      相关资源
      最近更新 更多