angular国际化

随着世界各地Web访问量的增加,作为开发者的我们也在不断让应用国际化、本地化。当用
户访问我们的应用时,他应该能够在运行时立即切换语言环境。
鉴于我们正在开发的是AngularJS客户端应用,尤其不希望用户必须刷新页面或者访问一个
完全不同的URL。当然,AngularJS可以很容易地调整那些国际化读者的本机语言环境,或许通
过为不同语言生成不同模板的方式为应用提供服务。
然而,这个过程可能会很麻烦,当我们想要改变应用的布局时会发生什么情况?每个独立的
模板都需要重新构建和部署。而这个过程应该是很简单才对。
27.1 angular-translate
你可以使用angular-translate来替代创建新模板的方式,这个AngularJS模块为你的应用提
供了i18n(国际化)服务。angular-translate要求创建一个JSON文件,它描述每种语言的翻译
数据。然后它只会在必要时从服务器延迟加载特定语言的翻译数据。
angular-translate库自带了很多内置指令和过滤器,这让我们的应用国际化变得简单。我
们一起来学习一下。
27.2 安装
为了使用angular-translate,需要加载这个库。可以使用几种不同的方式安装它,但是推
荐使用Bower。
Bower是一个前端包管理器。它不仅能够处理JavaScript库,还可以处理HTML、CSS以及图
片程序包。一个程序包就是一个简单的封装,典型的例子就是一个可公开访问的第三方代码库。
 使用Bower
使用标准的Bower方法安装angular-translate:
$ bower install angular-translate
此外,你也可以从Github下载压缩版的angular-translate。
安装好最新稳定版本的angular-translate之后,你就可以简单地将它嵌入到你的HTML文  

档中。只要确保它嵌入在Angular脚本之后,因为它依赖于angular库。
<script src="path/to/angular.js"></script>
<script src="path/to/angular-translate.js"></script>
最后一项要点是,在你的应用中必须将angular-translate声明为一个加载依赖:
var app = angular.module('myApp', ['pascalprecht.translate']);
很好!现在已经准备好使用angular-translate组件来翻译你的应用了。
27.3 教你的应用一种新语言
安装好angular-translate后,将它声明为应用的依赖,这样才可以用它来翻译应用程序的
内容。
首先,需要提供翻译数据,这样应用才能真正地说一种新的语言。这一步可以通过使用最新
的$translateProvider服务配置$translate服务实现。
培养应用使用一种新的语言很简单。只需在应用上使用config函数,为应用提供不同的语言
翻译(比如英语、德语、希伯来语等)。首先,需要将$translateProvider注入到配置函数中,
就像这样:
angular.module('angularTranslateApp', ['pascalprecht.translate'])
.config(function($translateProvider) {
// 翻译会放到这里
});
要添加一种语言,必须让$translateProvider找到一个翻译表格,这是一个JSON对象,它
包含将要翻译为具体值的消息(键)。使用翻译表格时允许我们将翻译数据编写为一个简单的
JSON文件,以便从远程加载或者在编译时设置,比如:
{
'MESSAGE': 'Hello world',
}
在翻译表格中,键(key)表示一个翻译ID,而其值表示某种语言特定的翻译数据。现在,
先给应用添加一个翻译表格。$translateProvider提供了一个叫做translations()的方法来处
理它。
app.config(function($translateProvider) {
$translateProvider.translations({
HEADLINE: 'Hello there, This is my awesome app!',
INTRO_TEXT: 'And it has i18n support!'
});
});
有了这个翻译表格之后,应用就可以使用angular-translate了。由于这是在配置期间添加
的翻译表格,因此在angular-translate的组件被实例化时就能访问到这个翻译表格了。
先切换到应用的模板部分。要将键绑定给视图很简单,只需添加翻译数据到视图层即可。使
用translate过滤器时,甚至不必接触控制器或者服务,或者无需担心视图层:因为你可以从任
何控制器或者服务中解耦翻译逻辑,并且无需接触业务逻辑代码就能让视图可替换。

从根本上说,translate过滤器的工作原理就像这样:
<h2>{{ 'TRANSLATION_ID' | translate }}</h2>
也可以使用这个translate过滤器来更新示例应用程序:
<h2>{{'HEADLINE' | translate }}</h2>
<p>{{'INTRO_TEXT' | translate}}</p>
很好!现在可以翻译视图层中的内容了,并且还避免了翻译逻辑污染控制器逻辑;然而,即
使我们不使用angular-translate也能得到完全相同的结果,因为在这个示例应用中只涉及一种
语言。
接下来我们一起看看angular-translate真正的能力,然后学习如何教应用多种语言。

27.4 多语言支持
前面我们已经通过translations()方法为应用添加了一个翻译表格。
正如translations()方法所设置的,$translateProvider识别了一种语言。现在,可以通
过提供第二个翻译表格以同样的方式添加一种新的语言。
设置第一个翻译表格时,我们可以给它提供一个键(语言键)来指定我们要翻译的语言。这
样可以使用不同的语言键添加不同的翻译。
更新一下应用,让它包含第二种语言:
app.config(function($translateProvider) {
$translateProvider.translations('en_US', {
HEADLINE: 'Hello there, This is my awesome app!',
INTRO_TEXT: 'And it has i18n support!'
});
});
为了给不同语言添加附加的翻译表格,比方说德语,我们只需使用不同的语言键做同样的事
情就行了。
app.config(function($translateProvider) {
$translateProvider.translations('en', {
HEADLINE: 'Hello there, This is my awesome app!',
INTRO_TEXT: 'And it has i18n support!'
})
.translations('de', {
HEADLINE: 'Hey, das ist meine großartige App!',
INTRO_TEXT: 'Und sie untersützt mehrere Sprachen!'
});
});
现在,应用能识别两种不同的语言了。你可以根据需要随意添加尽可能多的语言;但是,现
在这里有了两种有效的语言,那么应用如何知道该使用哪种语言呢?在你告诉它应该怎么做之
前,angular-translate不会推荐任何语言。
要设置首选语言,你可以使用$translateProvider.preferredLanguage()方法。这个方法
会告诉angular-translate哪种已注册语言是应用默认应该使用的语言。它要求使用一个语言键

值作为参数,这个参数指向某个翻译表格。
现在,我们来告诉应用应该使用英语作为默认语言:
app.config(function($translateProvider) {
$translateProvider.translations('en', {
HEADLINE: 'Hello there, This is my awesome app!',
INTRO_TEXT: 'And it has i18n support!'
})
.translations('de', {
HEADLINE: 'Hey, das ist meine großartige App!',
INTRO_TEXT: 'Und sie untersützt mehrere Sprachen!'
});
$translateProvider.preferredLanguage('en');
});

27.5 运行时切换语言
要在运行时切换到一种新语言,必须使用angular-translate的$translate服务。它有一个
use()方法,这个方法要么返回一个当前正在使用的语言对应的语言键,或者传递一个语言键作
为参数,这个参数会让angular-translate使用该参数对应的语言。
为了感受一下如何在真实的应用中运用这一功能,我们可以添加两个表示译文的翻译ID,稍
后添加到HTML模板中的按钮会用到这两个ID:
app.config(function($translateProvider) {
$translateProvider.translations('en', {
HEADLINE: 'Hello there, This is my awesome app!',
INTRO_TEXT: 'And it has i18n support!',
BUTTON_TEXT_EN: 'english',
BUTTON_TEXT_DE: 'german'
})
.translations('de', {
HEADLINE: 'Hey, das ist meine großartige App!',
INTRO_TEXT: 'Und sie untersützt mehrere Sprachen!'
BUTTON_TEXT_EN: 'englisch',
BUTTON_TEXT_DE: 'deutsch'
});
$translateProvider.preferredLanguage('en');
});
接下来,我们要使用$translate服务和它的use()方法在控制器上实现一个方法以便在运行
时改变语言。为此,要将$translate服务注入到应用的控制器中,然后添加一个函数给它的
$scope对象:
app.controller('TranslateController', function($translate, $scope) {
$scope.changeLanguage = function(langKey) {
$translate.use(langKey);
}
});
接着,我们通过为每种语言添加一个按钮的方式在HTML模板中反映这一变化。还必须在每
个按钮上设置一个ng-click指令在运行时调用改变语言的函数。
<div ng-controller="TranslateController">
<button ng-click="changeLanguage('de')" translate="BUTTON_TEXT_DE"></button>
<button ng-click="changeLanguage('en')" translate="BUTTON_TEXT_EN"></button>
</div>
瞧瞧!现在我们就拥有一个支持多语言的应用了。
27.6 加载语言
如果我们只是设置静态语言那多没劲啊!多亏了Angular的$http服务,我们可以通过
$translateProvider的registerLoader方法来动态加载语言。
首先,需要安装angular-translate-loader-url扩展来设置loader-url服务,它要求有一
个后端服务器通过处理lang参数的方式返回JSON数据。如果你已经有一个处理带lang参数路由
的后端程序,那么可以像这样使用Bower安装loader-url服务:
$ bower install angular-translate-loader-url
如果你更喜欢使用服务来加载静态文件,那么可以使用static-files加载器从语言路径中
加载JSON文件。由于这个路由程序很简单,这里将继续使用Bower来安装这个服务:
bower install angular-translate-loader-static-files
现在,先让我们确保已经使用script标签将这个文件载入视图中了:
<script src="/js/angular-translate-loader-url.min.js"></script>
为了配置服务以使用这个static-files加载器,你需要让$translateProvider使用一个配
置对象来启用这个加载器。这个配置对象接受两个参数:
 prefix指定文件前缀(含文件路径);
 suffix指定文件后缀(常见的扩展名)。
这个加载器试图从如下URL路径中获取文件:[prefix]/[langKey]/[suffix]。比如,如果
设置配置对象为:
$translateProvider.useStaticFilesLoader({
prefix: '/languages/',
suffix: '.json'
});
angular-translate 会试图从/languages/en_US.json 中加载en_US 语言。像这样使用
StaticFilesLoader时就带来了延迟加载的额外好处。在运行时$translate只会在需要语言文件
时才加载它。
当然,应用加载时,异步加载会导致未翻译的内容闪现。可以通过将应用自带语言设置为默
认语言的方式规避这一副作用。
最后还有一个很酷的特性:可以使用本地存储(local storage)功能存储语言文件。
angular-translate提供了使用本地存储的能力;你可以用一个函数来启用这一功能:
.config(function($translateProvider) {
$translateProvider.useLocalStorage();
});

<div ng-controller="TranslateController">
<button ng-click="changeLanguage('de')" translate="BUTTON_TEXT_DE"></button>
<button ng-click="changeLanguage('en')" translate="BUTTON_TEXT_EN"></button>
</div>
瞧瞧!现在我们就拥有一个支持多语言的应用了。
27.6 加载语言
如果我们只是设置静态语言那多没劲啊!多亏了Angular的$http服务,我们可以通过
$translateProvider的registerLoader方法来动态加载语言。
首先,需要安装angular-translate-loader-url扩展来设置loader-url服务,它要求有一
个后端服务器通过处理lang参数的方式返回JSON数据。如果你已经有一个处理带lang参数路由
的后端程序,那么可以像这样使用Bower安装loader-url服务:
$ bower install angular-translate-loader-url
如果你更喜欢使用服务来加载静态文件,那么可以使用static-files加载器从语言路径中
加载JSON文件。由于这个路由程序很简单,这里将继续使用Bower来安装这个服务:
bower install angular-translate-loader-static-files
现在,先让我们确保已经使用script标签将这个文件载入视图中了:
<script src="/js/angular-translate-loader-url.min.js"></script>
为了配置服务以使用这个static-files加载器,你需要让$translateProvider使用一个配
置对象来启用这个加载器。这个配置对象接受两个参数:
 prefix指定文件前缀(含文件路径);
 suffix指定文件后缀(常见的扩展名)。
这个加载器试图从如下URL路径中获取文件:[prefix]/[langKey]/[suffix]。比如,如果
设置配置对象为:
$translateProvider.useStaticFilesLoader({
prefix: '/languages/',
suffix: '.json'
});
angular-translate 会试图从/languages/en_US.json 中加载en_US 语言。像这样使用
StaticFilesLoader时就带来了延迟加载的额外好处。在运行时$translate只会在需要语言文件
时才加载它。
当然,应用加载时,异步加载会导致未翻译的内容闪现。可以通过将应用自带语言设置为默
认语言的方式规避这一副作用。
最后还有一个很酷的特性:可以使用本地存储(local storage)功能存储语言文件。
angular-translate提供了使用本地存储的能力;你可以用一个函数来启用这一功能:
.config(function($translateProvider) {
$translateProvider.useLocalStorage();
});

至此我们已经介绍了如何使用anguar-translate的$translateProvider.translations()
方法和translate过滤器为Angular应用提供i18n支持。此外还展示了如何使用$translate服务以
及它的use()方法在运行时改变语言。
你可以尝试一下angular-translate。它提供了很多非常棒的特性,比如处理多元化,使用
自定义加载器和通过服务设置翻译。它的文档非常出色,建议你在这里①查看它们。
那里还有很多可以直接用于你的站点的示例。同时它还是一个展示了所有可用组件和接口的
API参考手册②,这些都可以用于构建了不起的带有国际化支持的应用。
27.7 angular-gettext
类似于angular-translate,angular-gettext使用一个完不同方法提供了翻译功能。但它
不需要我们将想要翻译的字符串嵌入到应用中,而是抽象出特定的字符串让程序库处理它们。
Gettext是一个由GNU项目发起的国际化和本地化系统,该项目最早发布于1995年。它是一
个非常流行的支持新语言的系统,因为它可将字符串打包,以便稍后翻译。
angular-gettext库以同样的方式工作,它将稍后想要翻译的字符串包装起来。
27.8 安装
为了使用angular-gettext,首先需要加载anglar-gettext库。虽然可以使用几种不同的方
式安装它,但是我们推荐使用Bower。
 使用Bower
可以像这样使用Bower安装angular-gettext:
$ bower install --save angular-gettext
此外,你也可以从Github下载压缩版的angular-gettext。
安装了最新的稳定版的angular-gettext之后,就可以简单的将它嵌入到HTML文档中。只
需要确保在Angular之后嵌入,因为它依赖于核心的angular库以及jquery(因为它也是
angular-gettext的依赖项)。
<script src="path/to/jquery.js"></script>
<script src="path/to/angular.js"></script>
<script src="path/to/angular-gettext.js"></script>
最后一项要点是,在你的应用中必须将angular-gettext声明为一个加载依赖:
var app = module('myApp', ['angular-gettext']);
现在就已准备好使用angular-gettext的组件来翻译你的应用了。

angular-gettext库包含translate指令,这是一个简单的指令,它可以被放置在那些包含
你想要翻译的字符串的DOM元素上。
<h1 translate>Hello!</h1>
<h1>的内容将使用我们稍后会定义的字符串译本自动翻译。
与普通的字符串相比,待翻译的字符串也会以同样的方式处理,angular-gettext提供的功
能完全支持从应用内部插值。
<h1 translate>Hello {{name}}</h1>
这还可以支持翻译复数表示法。例如,比如你想要将apple翻译为它的复数形式apples。
<h1 translate>One apple</h1>
你可以添加两个甚至更多指令给<h1>元素,来表示当前计数以及要翻译的最终字符串。
<h1 translate
translate-n="count"
translate-plural="{{ count }} apples">
One apple
</h1>
如果translate-n表达式的结果大于1,那么gettext就使用translate-pural中的字符串;
否则,它使用DOM元素<h1>的值。
这个附加的translate-n指令接受任意形式的Angular表达式,包括函数。关于表达式的更多
信息,请查看第6章。
translate-pural就是一个简单的字符串,它会在这个指令被调用时替换DOM元素内的值。
最后,你还可以在应用内使用translate过滤器。因为有时候我们不能使用指令,例如:
<input type="text" placeholder="Username"/>
还可以使用translate过滤器来替换占位符中Username的值。
<input type="text" placeholder="{{'Username' | translate }}"/>

猜你喜欢

转载自blog.csdn.net/u012741119/article/details/82833495