angular2+国际化实践(ngx-translate方案)

来源:互联网 发布:金星妻子 知乎 编辑:程序博客网 时间:2024/06/08 11:40

背景

最近基于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的实例。当然,也可以放弃这些特性,使用公共的实例。

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

原创粉丝点击