我试图找出,如何在Angular模板中更新插值 - 如果值本身没有改变。
我有这样的陈述(例如翻译):
<div>{{ 'SOME_TAG' | lang }}</div>
这会启动过滤器
app.filter('lang', function(Locale) {
return function(val) {
return Locale.translate(val);
}
});
Locale是一种具有字段lang的服务,具体取决于哪些值被翻译成不同的语言。当我更改此字段的值时,翻译的值也应该更改。
像
这样的东西<select ng-model="lang" ng-change="changeLang()">
<option value="de">Deutsch</option>
<option value="en">English</option>
</select>
...
$scope.changeLang = function() {
Locale.changeLanguage($scope.lang);
};
在较早的AngularJS版本中(例如1.1.5,不知道有多远),这样做就好了。如果我更新Locale.lang值并运行$ digest()循环,则更新插值模板值。在最新版本(1.4.6但也是1.3.xx)中,这不再起作用了。 我认为这是一些优化的一部分 - 值(&#39; SOME_TAG&#39;)没有改变,所以为什么要重新运行插值。
我已经看到了http://angular-translate.github.io/这里的工作正常。 有没有&#34;技巧&#34;让这些值更新?
谢谢。
答案 0 :(得分:4)
在angular docs about过滤器中,有一个名为stateful
的内容。添加它是为了提高过滤器的性能。
有一个非常好的blog post关于状态过滤器的详细描述。
简而言之'SOME_TAG'
是一个字符串,永远不会更改,并且永远不会调用过滤器添加的$watch
。但是对于$stateful
,它还会检查过滤器的注入依赖项是否有变化。
因此您需要$stateful
或者您可以将语言范围变量传递给服务以使其正常工作。
我认为最好避免使用$stateful
过滤器(如文档中所推荐的那样),因为它们会更频繁地运行,然后无法运行。因此,通过语言范围会更好。
请查看下面的演示或此fiddle。
angular.module('demoApp', [])
.factory('Locale', Locale)
.filter('langStateful', LangFilterState)
.filter('lang', LangFilter)
.controller('MainController', MainController);
function MainController($scope, $timeout, Locale) {
$scope.changeLang = function() {
Locale.changeLanguage($scope.lang);
};
}
function LangFilter(Locale) {
function LangFilter(val, lang) {
return Locale.translateLang(val, lang);
}
return LangFilter;
}
function LangFilterState(Locale) {
function LangFilter(val) {
return Locale.translate(val);
}
LangFilter.$stateful = true;
return LangFilter;
}
function Locale() {
var localeFactory = {
language: 'de',
changeLanguage: changeLanguage,
translate: translate,
translateLang: translateLang,
tags: {
'title': {
de: 'Titel',
en: 'title'
},
'help': {
de: 'Hilfe',
en: 'help'
}
}
};
return localeFactory;
function changeLanguage(lang) {
this.language = lang;
}
function translate(tag) {
return this.tags[tag][this.language];
}
function translateLang(tag, lang) {
return this.tags[tag][lang];
}
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app="demoApp" ng-controller="MainController">
<select ng-model="lang" ng-change="changeLang()" ng-init="lang='de'">
<option value="de">Deutsch</option>
<option value="en">English</option>
</select>
{{'help' | langStateful}}
{{'title' | lang: lang}}
</div>
&#13;
答案 1 :(得分:0)
我对此感兴趣,所以我研究了角度翻译代码。
在他们的代码中,特别是在src/service/translate.js
和src/filter/translate.js
中,您会看到他们跟踪插值ID并在$translate.setLanguage()
之后更新插值对象。这是你的代码和他们的代码之间的唯一区别。
我的猜测是,角度将跟踪插值对象在摘要周期之间的变化,并重新运行已更改的插值,尽管它们的上下文没有改变,但我不会碰巧知道角度代码库这么好我可以证明这一点。这对我来说是有意义的,因为除了angular-translate的代码之外,我没有看到任何“诡计”。