AngularJS本地化,國際化
國際化,簡寫為i18n,指的是使產品快速適應不同語言和文化。
本地化,簡稱l10n,是指使產品在特定文化和語言市場中可用。
對開發者來說,國際化一個應用意味著將所有的文字和其他因地區而異的資料從應用中抽離出來。
本地化意味著為這些抽離的資料和文字提供翻譯和轉變成本地的格式。
目前,AngularJS支援日期,數字和貨幣的國際化和本地化。
另外,AngularJS還通過ngPluralize
指令支援本地多元化。
所有的AngularJS本地化元件都依賴於$locale服務,管理本地化規則(locale-specific rule sets)。
如果你想直接看例子,你可以在AngularJS開發包的i18n/e2e資料夾下找到這些例子。
一個地區(locale
)是指一個按地理上,政治上,文化上劃分的區域。常用的地區ID由兩部分組成:語言代號和國家代號。比如,en-US, en-AU, zh-CN就是合法的地區ID,它們都含有語言代號和國家代號。 因為國家代號是可選的。所以像en, zh, and sk這樣的id也是合法的。檢視ICU網站來獲取更多的地區ID資訊。
對於AngularJS支援的地區,AngularJS按照數字,事件格式等規則分別放在不同的檔案裡,每個檔案都對應一個指定的地區。你在AngularJS資料夾裡可以找到一系列支援的地區。
有兩種方法能使用新的地區規則:
1. 預捆綁規則
你可以通過將地區檔案與angular.js捆綁,來實現對你想要使用的地區檔案的預繫結。
比如在*nix系統中,你可以按照下面的命令,建立一個包含德國地區規則的angular.js檔案:
cat angular.js i18n/angular-locale_de-ge.js > angular_de-ge.js
當應用使用angular_de-ge.js指令碼而不是angular.js指令碼時,AngularJS會自動使用德國本地化規則。
2. 將地區指令碼載入到index.html
你也可以將指定的地區檔案載入到index.html中。比如,當有客戶端請求是來自德國的,你可以返回index_de-ge.html,這個檔案看起來像下面這樣:
<html ng-app>
<head>
….
<script src="angular.js"></script>
<script src="i18n/angular-locale_de-ge.js"></script>
….
</head>
</html>
第二種方式(在index.html中載入指令碼)要更慢一些,因為需要額外載入指令碼。
AngularJs的貨幣過濾器允許你使用地區服務裡的預設貨幣符號,但是你也可以使用你自己定義了貨幣符號的過濾器。如果你的應用只在一個地區使用,那麼使用預設的錢幣符很好。但是如果你的應用在多地區使用, 你應該提供你自己的錢幣符來確保錢幣值能被正確理解。
比如說,如果你想顯示1000美元的賬戶餘額,使用下面這種帶有錢幣過濾器的表示式{{1000|currency}},並且你的應用目前是在en-US地區,那麼'$1000.00'會被顯示出來。但是,如果使用者在其他地方使用(比如說,中國深圳)你的應用,它的瀏覽器會將地區指定成CN,'¥1000.00'就會被顯示出來。這會迷惑你的使用者。
在這個例子中,你需要通過自己指定錢幣過濾器來替換預設的錢幣符。這個過濾器要有一個你自己指定的錢幣符,比如USD$1,000.00。這樣,AngularJS就總是會顯示'USD$1000'並且忽略掉地區的轉換。
還有一點要記住,譯文的長度可能和原文有很大區別。比如說,June 3, 1977
在西班牙會被翻譯成3 de junio de 1977
。而且還有更多極端的情況,所以,在對你的應用進行國際化時,你需要好好的寫CSS規則並且做好測試。
最後要注意的是,AngularJS使用的是瀏覽器的時區設定。所以一個相同的應用會根據不同的裝置顯示不同的時間格式。Javascript和AngularJS都不能支援使用統一的開發者制定的時區。
相容IE低版本瀏覽器
如果你要讓你的AngularJS應用相容IE8和IE8以下版本的話,你需要仔細閱讀下面的知識點。
要讓你的AngularJS應用在IE中正常執行你必須:
確保JSON字串能被正常解析(IE7需要),你可以使用JSON2或者JSON3(這兩個東西是第三方庫,可以在github上下載)來實現。
你不能使用自定義的元素標籤,如
<ng:view>
(你只能使用屬性的形式,如<div ng-view>
),或者,如果你用了自定義的標籤名,那你必須按照以下步驟做才能保證IE正常執行:
<html xmlns:ng="http://angularjs.org">
<head>
<!--[if lte IE 8]>
<script>
document.createElement('ng-include');
document.createElement('ng-pluralize');
document.createElement('ng-view');
// Optionally these for CSS
document.createElement('ng:include');
document.createElement('ng:pluralize');
document.createElement('ng:view');
</script>
<![endif]-->
</head>
<body>
...
</body>
</html>
上面的程式碼需要知道的是:
xmlns:ng
- 名稱空間 - 你需要為你使用或者準備使用的每一個自定義標籤準備一個名稱空間。document.createElement
(你的標籤名) - 自定義標籤的建立 - 因為這只是老版本IE的一個問題,所以你需要根據情況使用。對於每一個你沒有使用名稱空間或者HTML中沒有定義的標籤,你需要預先宣告它才能使老版本IE正常工作。
還有一些細節需要注意:
IE處理非標準標籤名會產生問題。問題可以分為兩類,每類都有自己的解決方法。
如果標籤名是以
my:
字首開始的: 這會被當成是一個XML的名稱空間,並且必須使用一個名稱空間來宣告。如果標籤沒有
:
符號,但它又不是一個標準的HTML標籤。那麼就必須預先使用document.createElement('my-tag')
來建立它。如果你準備使用css選擇器來對自定義標籤新增樣式,那麼你就必須先用
document.createElement('my-tag')
來建立一下,不管有沒有XML名稱空間。
值得慶幸的是,IE的這種限制只存在標籤名上,標籤屬性名沒有限制。所以,當在IE上使用<div my-tag your:tag> </div>.
這樣的形式時,沒有特殊要求。
如果我沒按上面說的做會怎麼樣?
假設你用了一個非HTML標準的標籤,暫時稱為mytag(稱為my:tag 或者 my-tag都可以):
<html>
<body>
<mytag>some text</mytag>
</body>
</html>
它本該被解析成下面這樣的DOM:
#document
+- HTML
+- BODY
+- mytag
+- #text: some text
期望的結果是BODY元素包含一個叫做mytag
的子元素。這個子元素同時包含文字"some text"。
但是IE不會這樣解析(如果沒有按之前修復IE的步驟做的話):
#document
+- HTML
+- BODY
+- mytag
+- #text: some text
+- /mytag
在IE中,BODY元素有了三個子元素:
(1)一個自閉合的標籤mytag。和自閉合標籤一樣。最後的關閉符/是可選的,但是標籤並不允許包含子元素。所以瀏覽器會將some text解析成兄弟節點。
(2)一個純文字的節點。這本來應該是上面的mytag的子節點,而不是兄弟節點。
(3)一個不合法的自閉合標籤/mytag。 因為標籤名不允許含有/,所以說它是非法的。另外這個關閉標籤不應該是DOM的一部分,因為它是用來描述標籤的結尾位置的。
加油!