AngularJS刷新内插值

时间:2015-09-21 18:11:13

标签: javascript angularjs string-interpolation

我试图找出,如何在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;让这些值更新?

谢谢。

2 个答案:

答案 0 :(得分:4)

angular docs about过滤器中,有一个名为stateful的内容。添加它是为了提高过滤器的性能。

有一个非常好的blog post关于状态过滤器的详细描述。

简而言之'SOME_TAG'是一个字符串,永远不会更改,并且永远不会调用过滤器添加的$watch。但是对于$stateful,它还会检查过滤器的注入依赖项是否有变化。

因此您需要$stateful或者您可以将语言范围变量传递给服务以使其正常工作。 我认为最好避免使用$stateful过滤器(如文档中所推荐的那样),因为它们会更频繁地运行,然后无法运行。因此,通过语言范围会更好。

请查看下面的演示或此fiddle

&#13;
&#13;
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;
&#13;
&#13;

答案 1 :(得分:0)

我对此感兴趣,所以我研究了角度翻译代码。

在他们的代码中,特别是在src/service/translate.jssrc/filter/translate.js中,您会看到他们跟踪插值ID并在$translate.setLanguage()之后更新插值对象。这是你的代码和他们的代码之间的唯一区别。

我的猜测是,角度将跟踪插值对象在摘要周期之间的变化,并重新运行已更改的插值,尽管它们的上下文没有改变,但我不会碰巧知道角度代码库这么好我可以证明这一点。这对我来说是有意义的,因为除了angular-translate的代码之外,我没有看到任何“诡计”。