Skip to main content

i18n 翻譯

template 引用 i18n

透過用 pipe

<p>{{ 'global.dialog.blacklist.title' | translate }}</p>

透過 js 直接翻譯

constructor(private translate: TranslateService) {}
const msg = this.translate.instant('global.dialog.blacklist.title')
// 參數的寫法
// translate.instant('demo.greeting', {name: 'John'});

比較不推薦的寫法

<element [translate]="'id'"></element>
<element translate>id</element>

translate parameters

{
"demo": {
"title": "Translation demo",
"text": "This is a simple demonstration app for ngx-translate",
"greeting": "Hello {{name}}!"
}
}
translate.instant('demo.greeting', {name: 'John'});
<p>{{ 'demo.greeting' | translate : {name: 'John'} }}</p>
<li [translate]="'demo.greeting'" [translateParams]="{name: 'John'}"></li>

isolate 作用

TranslateModule.forChild({
defaultLanguage: 'en',
loader: {
provide: TranslateLoader,
useFactory: translateFactory,
deps: [TransferState],
},
isolate: true,
}),

GitHub - larscom/ngx-translate-module-loader: Highly configurable and flexible translations loader for @ngx-translate/core Lazy-loaded modules dont get their translations when "isolate" is false. · Issue #1193 · ngx-translate/core · GitHub

Ngx-Translate

延遲載入 i18n JSON

GitHub - larscom/ngx-translate-module-loader: Highly configurable and flexible translations loader for @ngx-translate/core Ngx Translate Module Loader - StackBlitz


只用 @ngx-translate/core 的寫法

import { appTranslateFactory } from './custom-translate-loader';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';

@NgModule({
declarations: [],
imports: [
TranslateModule.forRoot({
defaultLanguage: 'en',
loader: {
provide: TranslateLoader,
useFactory: appTranslateFactory, // call function return class and getTranslation
deps: [TransferState],
},
}),
],
providers: [],
bootstrap: [AppComponent],
})

export function appTranslateFactory(transferState: TransferState) {
return new CustomTranslateLoader(['component'], transferState);
}

export class CustomTranslateLoader implements TranslateLoader {

constructor(private types: string[], private transferState: TransferState) {
this.types = types;
}

public getTranslation(lang: string): Observable<any> {
const key: StateKey<number> = makeStateKey<number>(`transfer-translate${this.types.join('-')}-${lang}`);
const data = this.transferState.get(key, null);

// 優先使用 Server 暫存的資料。如果沒有才重新發出請求。
if (data) {
return from([data]);
} else {
const observableLangMaps = [];
for (const type of this.types) {
observableLangMaps.push(from(import(`../../../assets/i18n/${type}/${lang}.json`)));
}
const combined = zip(...observableLangMaps);
return combined.pipe(
map((val) => {
const last = {};
for (const langObj of val) {
Object.assign(last, langObj);
}
const key: StateKey<number> = makeStateKey<number>(`transfer-translate${this.types.join('-')}-${lang}`);
this.transferState.set(key, last);
return last;
}));
}
}

}

GitHub - ngx-translate/core: The internationalization (i18n) library for Angular

其它套件

npm i @larscom/ngx-translate-module-loader

主要也是在取代 @ngx-translate/http-loader 的使用。

這個是此套件的 demo Ngx Translate Module Loader (forked) - StackBlitz

主要的好處:

  1. 可以在 import 的時候,直接透過 obj 作出 lazy-loaded
  2. GitHub - thomas-chu-30/angular-translate: 為了在打包後可以透過改變 JSON 來直接更新翻譯檔案
    • 經過測試後,此套件可以在 build 完之後,直接改動 asset 裡面的 JSON 檔案,就可以直接進行 content 的更新 👍
 modules: [ 
// final url: ./assets/i18n/en.json
{ baseTranslateUrl },
// final url: ./assets/i18n/feature1/en.json 這個 feature1 就會是 lazy load
{ baseTranslateUrl, moduleName: 'feature1' },
// final url: ./assets/i18n/feature2/en.json 這個 feature2 就會是 lazy load
{ baseTranslateUrl, moduleName: 'feature2' }, ],

加載完成後在執行 function

如果在使用TranslateService 的即時方法獲取新的文字時,獲取到的是上一種語言的文本,這可能是因為TranslateService 的即時方法是立即返回文本的,而不是語言切換完成。要確保等待獲取到的文字與目前語言匹配,您可以在語言切換之後使用 TranslateService 的 get 方法。

以下是一個範例,以繁體中文的方式解釋如何處理這個問題:

import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Component({
selector: 'app-your-component',
template: `
<div>
{{ translatedText }}
</div>
<button (click)="changeLanguage('en')">切換到英文</button>
<button (click)="changeLanguage('fr')">切換到法文</button>
`
})
export class YourComponent {
translatedText: string;

constructor(private translateService: TranslateService) {
this.translatedText = this.translateService.instant('your.translation.key');
}

changeLanguage(language: string) {
this.translateService.use(language).subscribe(() => {
// 當語言切換完成後執行的的操作
// 這裡可以更新文本
// ⭐️ **關鍵寫法**
this.translateService.get('your.translation.key').subscribe((text: string) => {
this.translatedText = text;
});
});
}
}

在上面的範例中,我們在元件建構函數中使用即時方法來初始化翻譯文本,然後在切換語言後,使用 get 方法來獲取新的文本。這種方法確保獲取到的文本與當前語言匹配。

請確保將 'your.translation.key' 替換為您實際的翻譯鍵。