最近基于angular 4.4.3和ionic 3.7.1写了一个lazyload的小程序,做i18n的一些实践整理。
angular@4.4.4, ionic@3.7.1, @ngx-translate/core@8.0.0, @ngx-translate/http-loader@2.0.0
可以在AppModule或者自定义的公共组件模块中去加载TranslateModule。
比如:
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {TranslateModule} from '@ngx-translate/core';
@NgModule({
imports: [
BrowserModule,
TranslateModule.forRoot()
],
bootstrap: [AppComponent]
})
export class AppModule { }
或者:
@NgModule({
exports: [
CommonModule,
TranslateModule
]
})
export class SharedModule { }
这里要注意点:在AppModule中导入的时候,使用了forRoot()方法,但是在公共模块SharedModule中导入的时候,不能使用TranslateModule.forRoot()方法。这样可能会使得整个依赖注入树中存在多个TranslateModule的实例。如果有必要的话,倒是可以使用TranslateModule.forChild()方法.
在懒加载的模块中,我们需要使用下面的方式:
@NgModule({
imports: [
TranslateModule.forChild({
loader: {provide: TranslateLoader, useClass: CustomLoader},
compiler: {provide: TranslateCompiler, useClass: CustomCompiler},
parser: {provide: TranslateParser, useClass: CustomParser},
missingTranslationHandler: {provide: MissingTranslationHandler, useClass: CustomHandler},
isolate: true
})
]
})
export class LazyLoadedModule { }
因为懒加载模块可以使用独立的loader,compiler,parser,所以可以在这里进行额外配置,甚至可以使用isolate:true来要求创建一个独立的TranslateModule的实例。当然,也可以放弃这些特性,使用公共的实例。
因为我们使用了ionic,所以需要在导入TranslateModule的时候做一些配置。
import {HttpClientModule, HttpClient} from '@angular/common/http';
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
/**
*// AoT like ionic requires an exported function for factories
*/
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
@NgModule({
imports: [
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient]
}
})
],
bootstrap: [AppComponent]
})
export class AppModule { }
其中./assets/i18n/
路径下有着一些json格式的国际化映射关系。
比如:有一个中文映射集:zh.json
{
"sudoku": "数 独",
"Game Center": "游戏中心",
"Level": "等级",
"Kindergarten": "幼儿园",
"Pupil": "小学生",
"Junior": "初中生",
"Senior": "高中生",
"Bachelor": "学士",
"Master": "硕士",
"Doctor": "博士",
"Genius": "天才",
"Godlike": "半神",
"Legendary": "传说",
"Change": "换 题",
"Check": "检 查",
"Peek": "提 示",
"Congratulations":"恭 喜",
"Congratulations_MSG":"恭喜完成此道数独,你很棒棒哟^_^",
"Sorry":"抱 歉",
"Sorry_MSG":"你还没有正确地完成此道数独,要不再试试?XD",
"TryHarder":"下一难度",
"TryMore":"再来一题",
"Cancel":"取消",
"OK":"确认"
}
可以以依赖注入的方式获取到TranslateService的实例,进行初始化之后就可以直接当作管道使用。
初始化:
constructor(public translate:TranslateService){
let browserLang = translate.getBrowserLang();
translate.use(browserLang.match(/en|zh/) ? browserLang : 'en');
// translate.use('en');
}
当管道使用:
<ion-header>
<ion-navbar color="primary">
<ion-title >
<span class="lsp1px">{{'Game Center'|translate}}</span>
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-card *ngFor="let item of games" (click)="gotoGame(item.page)">
<img class="game-icon" [src]="item.img">
<button ion-button full color="secondary"><span class="lsp1px">{{item.name|translate}}</span></button>
</ion-card>
</ion-list>
</ion-content>
直接调用API进行转化:
check() {
if (SudokuChecker.checkMatrix(this.matrix)) {
this.uiService.presentAlert({
title: this.translate.instant("Congratulations"),
message: this.translate.instant("Congratulations_MSG"),
buttons: [
{
text: this.translate.instant("TryHarder"),
handler: () => {
this.level++;
this.initPuzzle();
}
},{
text: this.translate.instant("TryMore"),
handler: () => {
this.initPuzzle();
}
}, {
text: this.translate.instant("Cancel"),
handler: () => {
return;
}
}
]
});
} else {
this.uiService.presentAlert({
title: this.translate.instant("Sorry"),
message: this.translate.instant("Sorry_MSG"),
});
}
}
这里调用了instant()方法。
完整项目代码:
https://github.com/ACEsLegendary/sudoku
项目演示:
https://aceslegendary.github.io/sudoku-demo
ngx-translate资源:
https://github.com/ngx-translate/core