Ngx translate与共享/惰性加载模块

28

可能是最常见的问题之一,虽然我找到了文档和一些其他问题,试图为我澄清一些事情,但我仍然不确定如何解决这个问题。

所以这是我的结构:

enter image description here

  • App模块当然是被引导的主模块
  • Countryselector模块:负责加载默认国家(基于IP)并负责根据浏览器决定使用什么语言。它基本上是决定使用哪个国家/语言的核心功能+它包含一个下拉菜单,供用户更改国家/语言。
  • Checkout模块、选择模块、支付模块都是使用路由进行延迟加载的。

AppModule

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http);
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    HttpClientModule,
    BrowserModule,
    AppRoutingModule,
    ContrySelectorModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  export class AppModule { }

国家选择器模块

@NgModule({
  declarations: [CountryselectorComponent],
  imports: [
    CommonModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  exports: [
    CountryselectorComponent
  ]
})
export class ContrySelectorModule { }

选择模块:

@NgModule({
  declarations: [SelectionComponent],
  imports: [
    CommonModule,
    SelectionRoutingModule,
    UspblockModule,
    TranslateModule.forChild({//or forRoot, no idea how to configure this
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }})
  ],
})
export class SelectionModule { }

现在的问题是,我不想在懒加载模块中再次进行语言配置,因为国家选择器模块已经处理了这个问题。我现在不确定如何正确配置懒加载模块(实际上也不确定countrySelectorModule是否正确)。使用标准github文档,我无法完成此操作。我已经尝试过对.forChild()进行调整,但迄今为止没有成功。

我需要一个分享模块吗?我需要在每个地方都导入countrySelectorModule(不推荐)吗?自定义装载程序?说实话,我不知道,而且文档对于更高级的场景来说有点短。

1个回答

37

我通过以下方法解决了这个问题:

  1. 创建一个 SharedModule,包含以下代码

SharedModule

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http);
}

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    TranslateModule.forChild({
      loader: {
      provide: TranslateLoader,
      useFactory: HttpLoaderFactory,
      deps: [HttpClient]
    },
    isolate: false
}),
  ],
  exports: [TranslateModule],
})
export class SharedModule {

  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SharedModule,
      providers: [ShoppingCartService, AccountService]
    }
  }
}

因此,这确保了每个导入SharedModule的模块都使用相同的配置TranslateModule。请确保导出它。同时,forRoot()也解决了确保ShoppingCartServiceAccountService只有一个实例而不是每个懒加载模块创建一个单独的服务。

3. 更改AppModule

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    HttpClientModule,
    BrowserModule,
    AppRoutingModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      },
      isolate : false
    }),
    SharedModule.forRoot(),
    ContrySelectorModule,
    
  ],
  providers: [    ],
  bootstrap: [AppComponent]
})
export class AppModule { }

既然AppModule是您的主入口点,请在此处对TranslateModuleSharedModule进行forRoot()调用。

  1. 任何懒加载的模块只需导入SharedModule,无需进行任何方法调用。同样,在我的示例中,CountrySelectorModule只需导入SharedModule,不需要导入其他任何内容。

你的“ContrySelectorModule”没有进行懒加载。你在app.module中导入了你的模块,所以无法使用懒加载功能。如果你有真正的懒加载模块,那么TranslateModule的解决方案将不起作用。 - Develobba
CountrySelectorModule 是主页面的一部分,因此被导入到 AppModule 中。我非常确定这个设置适用于惰性加载模块,尽管示例可能有点偏差。 - CularBytes
有另一种解决方案。在app.module中使用TranslateModule.forRoot,共享模块仅在惰性加载模块中导入,并且shared.module需要TranslateModule.forChild({extend:true})。 - Develobba
不确定 extended 是什么,但其余部分与我的代码类似。 - CularBytes
1
使用 Angular 13+:不要再使用 static forRoot(): ModuleWithProviders { ... },而是使用以下代码:static forRoot(): ModuleWithProviders<AppModule> { ... } - M. Al Jumaily
@CularBytes,你能否在Stackblitz上创建你的实现呢?我也在做同样的任务,如果你提供了你的Stackblitz实现,这会对我很有帮助。谢谢 :) - Mr. Learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接