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

AngularJS - how to trigger filter on 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>

从 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;
    });

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