请注意,AngularJS 模板只在应用程序引导期间编译一次,只要您不自己使用 $compile。
AngularJS 编译和链接阶段
要了解为什么您的代码不工作,您必须了解 AngularJS 编译和链接阶段。一旦你加载你的应用程序,AngularJS 会编译 HTML 元素,它包含一个带有 $compile 服务的 ng-app 属性,例如
<html ng-app="MyApp"></html>
编译阶段
$compile 标识 HTML 模板中的所有指令,调用每个指令的 compile 函数,从角度根元素 ($rootElement) 向上通过 html dom 树。
链接阶段
每个编译函数都返回一个后链接和一个可选的预链接函数。一旦 AngularJS 在根元素下编译了整个 dom,它就会开始调用 pre-link 函数,就像之前调用 compile 函数一样。一旦到达 dom 的叶子,指令的后链接函数就被称为返回到根元素。
插值
在 {{ 和 }} 之间具有表达式的字符串由 AngularJS 处理为称为插值指令的特殊指令。就像任何其他指令一样,这些指令是在编译期间使用 $interpolate 服务创建的。$interpolate 服务接收一个带有多个表达式的插值字符串并返回一个插值函数。interpolate 指令的 post-link 函数在 interpolate 函数上创建一个监视,以便一旦插入字符串中的任何表达式发生更改,它们就可以更新 html 节点。
翻译模块
当我们现在查看您的代码时,您实际上是在将 html 元素的文本设置为 AngularJS 插值字符串,并在指令的 post-link 函数中使用包含在 {{ 和 }} 之间的表达式。
如上所述,此时 AngularJS 已经编译了模板,因此它永远不会使用您的表达式编译内插字符串。
正如我从您的代码中看到的那样,您正在尝试实现某种翻译指令。此类指令在应考虑已翻译字符串中的插值字符串和其他 AngluarJS 模板代码时必须调用 $compile 函数:
directive('translate', ['$compile','translate', function factory($compile, translate) {
return {
priority: 10, // Should be evaluated before e. g. pluralize
restrict: 'ECMA',
link: function postLink(scope, el, attrs) {
if (el.contents().length) {
el.html(translate(el.text()));
$compile(el.contents())(scope); // This is only necessary if your translations contain AngularJS templates
}
},
};
}]).
translate 指令使用翻译服务来获取实际的翻译。translateProvider 有一个 add 方法,您可以使用它来添加翻译,例如从语言包中添加翻译:
.provider('translate', function() {
var localizedStrings = {};
var translateProvider = this;
this.add = function(translations) {
angular.extend(localizedStrings, translations);
};
this.$get = ['$log', '$rootScope', function ($log, $rootScope) {
var translate = function translate(sourceString) {
if (!sourceString) {
return '';
}
sourceString = sourceString.trim();
if (localizedStrings[sourceString]) {
return localizedStrings[sourceString];
} else {
$log.warn('Missing localization for "' + sourceString + '"');
return sourceString;
}
};
return translate;
}];
}).
config(function(translateProvider) {
translateProvider.add({'My name is {{name}}': 'Mi nombre es {{name}}'}); // This might come from a bundle
}).
使用模块
您现在可以按如下方式使用该模块:
<div ng-app="myApp" ng-controller="MyCtrl">
<span data-translate>My name is {{name}}</span>
</div>
我创建了一个带有完整示例的 jsFiddle:http: //jsfiddle.net/jupiter/CE9V4/2/