我想在 Angular 5 项目延迟加载模块中实现 ngx-translate,它仅适用于父模块,但不适用于我的子模块,因此请建议更好的解决方案。
我为应用程序模块编写代码。
我正在使用@ngx-translate/core 和 @ngx-translate/http-loader
app.module.ts
TranslateModule.forRoot({
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
LayoutModule,
HttpClientModule,
BrowserAnimationsModule,
HttpModule, ReactiveFormsModule,
RouterModule.forRoot(
appRoutes,
{ enableTracing: false }
),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient]
}
})
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/app/', '.json');
}
child.module.ts
@NgModule({
imports: [
RouterModule,
CommonModule,
BrowserModule,
BrowserAnimationsModule,
GridModule,
DropDownsModule,
FormsModule,
ExcelModule,
ControlMessagesModule, ReactiveFormsModule,
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: (AdminTranslateLoader),
deps: [HttpClient]
},
isolate: true
})
],
export function AdminTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/admin/', '.json');
}
我遇到了类似的问题,我在 SharedModule 中调用 TranslateModule.forRoot():
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
这个 SharedModule 是由我所有其他 lazy-loaded 模块导入的。 我有一个 menu-bar 子组件,带有一个切换语言的按钮。该组件以构造函数的常用方式通过注入获取TranslateService:
constructor(private translate: TranslateService) { }
调用
TranslateService.use('[LANG-CODE]')
确实会更改我的菜单栏组件中的翻译。但它并没有改变任何其他子组件的翻译。
我在 github 上发现了这个(相当老的)问题,基本上说我们不应该在 SharedModule 中调用 TranslateModule.forRoot()。
github 问题 - TranslateModule.forRoot 不应放在 SharedModule 中
所以我按照建议将
TranslateModule.forRoot()
移动到AppModule
中,并导出TranslateModule
。然后我在我的 TranslateModule
中导入和导出 SharedModule
。
完成此操作后,调用
TranslateService.use()
也会翻译其他子组件的文本,而不仅仅是调用该函数的文本(在我的例子中为 menu-bar
)
希望其他有类似问题的人会发现这很有用。
我的
Angular 12
项目也遇到了同样的问题。
将项目配置为:
TranslateModule.forRoot()
中添加了app.module.ts
,例如export function httpLoaderFactory(http: HttpClient){
return new TranslateHttpLoader(http);
}
@NgModule({
declarations: [
AppComponent
],
imports: [
TranslateModule.forRoot(
{
loader: {
provide: TranslateLoader,
useFactory: httpLoaderFactory,
deps: [HttpClient]
}
}
),
]
})
export class AppModule { }
TranslateModule
中导入和导出SharedModule
。import { NgModule, OnChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
@NgModule({
declarations: [],
imports: [
CommonModule,
TranslateModule
],
exports: [
TranslateModule
]
})
export class SharedModule { }
SharedModule
。共享模块概念无论如何都是一个正确的解决方案,但是调用子模块并更改
forChild()
在角度12中对我有用。
TranslateModule.forChild({
loader: {
provide: TranslateModule,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
这是一个错误...解决方法是确保在模块加载时重新初始化语言。为此,我将此构造函数添加到所有延迟加载的模块中:
constructor(protected translateService: TranslateService) {
const currentLang = translateService.currentLang;
translateService.currentLang = '';
translateService.use(currentLang);
}
下面的代码在 Angular 9 中对我有用。
注意:请将“moduleName”替换为您的应用程序模块名称。
对于延迟加载的模块,您可以将 lang 文件按模块放置在不同的文件夹中,并像这样从组件中引用它们。
export function moduleNameHttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, '/assets/i18n/moduleName/',
'.json');
}
您可以将以下代码添加到延迟加载模块中的导入中,即 moduleName.module.ts 文件中。
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: moduleNameHttpLoaderFactory,
deps: [HttpClient]
},
isolate: true
})
对于非延迟加载的模块,你可以这样做
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, '/assets/i18n/', '.json');
}
在 app.module.ts 文件中:-
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
},
isolate: true
})
我认为你必须设置默认语言!例如:
export class ChildModule {
constructor(private readonly translate: TranslateService) {
translate.setDefaultLang(translate.getBrowserLang());
}
}