AngularJS I18n 五部曲

細翻翻看歷史文章,其實關於Angular的總結已經有了不少,然而實際開發和測試工作中發現關於Angular的i18n bug依然層出不窮。近日又碰到一個“頁面未載入,請返回上一個頁面或重新整理頁面再試一次”的問題,而App本應該向用戶展示一個帶有date-picker的頁面,如下圖所示。

打開console會發現如下的錯誤信息。

個人看來,凡是在某個問題上不斷犯錯,正如“大師兄,師傅和二師兄又被妖怪抓走了”……再好似段譽的六脈神劍時靈時不靈的情景,大抵上是因爲依然沒有理解該問題癥結所在,同時並未掌握解決該問題的套路和招式。不揣冒昧,這裏嘗試提出解決AngularJS i18n問題的五部曲。

1. 添加需要支持的所有locale

如果我們希望Angular pipes同時支持所有locale默認對應的時間,日期,貨幣,小數點,千分位,百分號之類的格式,請務必執行改步驟。因爲Angular默認使用en-US作爲語言環境,沒有考慮其他。如果我們需要支持zh等locale,就需要在app.module.ts中進行配置,示意代碼如下。

import { registerLocaleData } from '@angular/common';
import locale_zh from '@angular/common/locales/zh'; 
registerLocaleData(locale_zh, 'zh');
// 注意zh這裏僅僅表示簡體中文,一旦需要繁體臺灣,繁體香港,請import zh-Hant, zh-Hant-HK

2. 設置當前locale

Angular會讀取名爲LOCALE_ID的注入令牌來設置當前的語言環境。這意味着我們每次必須根據所需使用的語言環境來更改該令牌,如下所示:

providers: [{provide: LOCALE_ID, useValue: 'zh-Hans' }]

如果我們希望支持用戶在runtime的時候來切換語言環境,則必須創建一個類或工廠函數來讀取該值,示意代碼如下:

export class DynamicLocaleId extends String {
  locale: string;

  toString() {
    return this.locale;
  }
}

...

providers: [
  ...
  { provide: LOCALE_ID, useClass: DynamicLocaleId }

],

3. 對所有文本使用翻譯策略

Angular 通過在HTML元素上使用簡單的i18n屬性來支持文本翻譯,這種實現方式最大的問題就是——每種語言都需要一個構建。也就是說,如果我們期望支持六種自然語言,則需要在不同的文件夾中部署6種不同的內部版本,同時在runtime切換到另一種語言需要重新加載應用程序。所以實踐中我們大多放棄該策略,轉而使用ngx-translate來處理i18n的原因。

4. 安裝配置ngx-translate

5. 使用ngx-translate

關於4-5部分,細節內容非常多,需要單獨的文章進行詳述,本文僅爲Angular的使用套路做個框架性的勾勒和白描,故不多累述。
 

閒言少敘,使出招式一,添加我們所需要的所有locale

public registerAngularLocaleData(culture: string): Promise<void> {
...

private initLocalization$(context: ApplicationContext): Observable<ApplicationContext> {
...

return import(
    `@angular/common/locales/${culture}.js`
)

.then((locale) => {
    registerLocaleData(locale.default);
});
...

const culture = context.locale.split('-')[0];
...

const angularLocalizationInit$ = culture === 'en' ? of(true) : this.registerAngularLocaleData(culture);

只一招,頁面無法正常顯示的問題似乎煙消雲散了。萬事大吉,收工了事?其實不然,細心的同學一定已經發現,這裏我們使用了locale.split導致只import並register了zh這樣的locale,而zh-Hant,zh-Hant-HK的細分市場完全被忽略了。不信就讓我們重新打開帶有date-picker的頁面看看現在顯示的是“週日”還是“週日”吧。

 

發佈了73 篇原創文章 · 獲贊 46 · 訪問量 67萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章