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的一部分,因为它是用来描述标签的结尾位置的。
文章来源:AngularJS开发指南7:AngularJS本地化,国际化,以及兼容IE低版本浏览器