angular2+國際化實踐(ngx-translate方案)

背景

最近基於angular 4.4.3和ionic 3.7.1寫了一個lazyload的小程序,做i18n的一些實踐整理。

框架

[email protected], [email protected], @ngx-translate/[email protected], @ngx-translate/[email protected]

導入

非懶加載模塊部分

可以在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的實例。當然,也可以放棄這些特性,使用公共的實例。

配置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

可以以依賴注入的方式獲取到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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章