请注意,AngularJS 模板只在应用程序引导期间编译一次,只要您不自己使用 $compile。
AngularJS 编译和链接阶段
要了解为什么您的代码不工作,您必须了解 AngularJS 的编译和链接阶段。一旦你加载你的应用程序,AngularJS 会编译 HTML 元素,该元素包含一个带有 $compile 服务的 ng-app 属性,例如。 g.
<html ng-app="MyApp"></html>
编译阶段
$compile 标识您的 HTML 模板中调用每个指令的编译函数的所有指令,该函数从您的角度根元素 ($rootElement) 向上通过 html dom 树。
链接阶段
每个编译函数都返回一个后链接和一个可选的预链接函数。一旦 AngularJS 在根元素下编译了整个 dom,它就会开始调用 pre-link 函数,就像它之前调用 compile 函数一样。一旦到达 dom 的叶子,指令的 post-link 函数就会被调用并返回到根元素。
插值
在 {{ 和 }} 之间具有表达式的字符串由 AngularJS 作为称为插值指令的特殊指令处理。就像任何其他指令一样,这些指令是在编译期间使用 $interpolate 服务创建的。 $interpolate 服务接收一个带有多个表达式的插值字符串并返回一个插值函数。 interpolate 指令的 post-link 函数在 interpolate 函数上创建一个监视,以便一旦插入字符串中的任何表达式发生更改,它们就可以更新 html 节点。
翻译模块
当我们现在查看您的代码时,您实际上是在将 html 元素的文本设置为 AngularJS 插值字符串,并在您的指令的链接后函数中的 {{ 和 }} 之间包含一个表达式。
正如上面所解释的,此时 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
}
},
};
}]).
翻译指令使用翻译服务来获取实际翻译。 translateProvider 有一个 add 方法,您可以使用它来添加翻译 e。 G。来自语言包:
.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/