当前位置: 首页 > 工具软件 > ngx-ui > 使用案例 >

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

有德业
2023-12-01

背景

最近基于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

 类似资料: