AngularJS - 如何在ng-click上触发过滤器

时间:2015-06-26 13:09:47

标签: javascript angularjs angularjs-scope angularjs-filter angularjs-ng-click

我试图制作简单的多语言网站。 我有一个小控制器,只是为了能够改变根范围内的当前语言:

   app.controller('Ctrl', function($scope, $rootScope) {
       $rootScope.currentLang = 'en_US';
       $scope.switchLang = function(){
            if($rootScope.currentLang ==='en_US'){
                $rootScope.currentLang = 'cs_CS';
            } else {
                $rootScope.currentLang = 'en_US';
            }
        }
    });

我想将数据存储在过滤器中:

   app.filter('ci18n', function($rootScope){
       return function(id_text){
           var translations = {
               'en_US' : {
                   'GREETING' : 'Hi'
               },
               'cs_CS' : {
                   'GREETING' : 'Cau'  
               }
            };

            return translations[$rootScope.currentLang][id_text];
        };
    });

问题是我的网站没有随rootScope更改而改变。 我需要一个想法,如何更好地解决它或如何再次触发过滤器来改变我的文本。

以下是我如何使用过滤器

<p>greet: {{'GREETING' | ci18n}}</p>

1 个答案:

答案 0 :(得分:14)

从Angular 1.3开始,filters are assumed to be stateless以便在常见情况下加快速度。这意味着如果输入没有改变,Anguar将不会重新评估你的过滤器。 Angular不知道您还在过滤器实现中阅读$rootScope.currentLang,因此如果currentLang发生更改,则不知道需要重新评估过滤器。

解决方案是将您的过滤器明确标记为有状态:

    app.filter('ci18n', function($rootScope){
       var filter = function(id_text){
           var translations = {
               'en_US' : {
                   'GREETING' : 'Hi'
               },
               'cs_CS' : {
                   'GREETING' : 'Cau'  
               }
            };

            return translations[$rootScope.currentLang][id_text];
        };

        filter.$stateful = true; // <-- the magic line

        return filter;
    });

当然这会带来性能损失,但由于您的过滤器只是一个地图查找,因此不应产生太大影响。