以下有效:
<script>
angular.module('myApp', [])
.filter('myFilter', ['$rootScope', function($rootScope) {
return function(v) {
return $rootScope.capitalize ? (v && v.toUpperCase()) : v;
};
}])
.controller('myController', ['$rootScope', '$scope', function($rootScope, $scope) {
$scope.flipCapitalize = function() {
$rootScope.capitalize = !$rootScope.capitalize;
}
}]);
</script>
{{"Hello" | myFilter }}
<div ng-controller="myController">
<button ng-click="flipCapitalize()">flip</button>
</div>
当您按下按钮时,屏幕上的“Hello”字样在混合大小写和大写字母之间翻转。
但是Angular并不“知道”它应该重新调用过滤器函数。它只是这样做,因为点击重新启动摘要外观并重新执行所有操作。
我的问题:这种行为有保障吗?我是否可以始终假设过滤器将在摘要循环中重新调用,并且我可以使用我能找到的任何范围内的任何数据?或者我是否幸运?
我的第二个问题:如果在每个摘要循环中重新调用过滤器函数,是否有某种方法可以打败这种行为?我可以告诉它,除非参数已经改变,不要再调用这个函数,你会得到相同的答案吗?或者我必须手工记忆?
答案 0 :(得分:1)
根据angular docs,如果您想保证过滤器正常工作,则需要使用过滤器的$stateful
属性将其标记为“有状态”。
强烈建议不要编写有状态的过滤器,因为Angular无法优化这些过滤器的执行,这通常会导致性能问题。只需将隐藏状态作为模型公开并将其转换为过滤器的参数,就可以将许多有状态过滤器转换为无状态过滤器。
如果您确实需要编写有状态过滤器,则必须将过滤器标记为$ stateful,这意味着它将在每个$ digest循环期间执行一次或多次。
因此,您应该将过滤器标记为有状态以保证该行为:
.filter('myFilter', ['$rootScope', function($rootScope) {
var filter = function(v) {
return $rootScope.capitalize ? (v && v.toUpperCase()) : v;
};
filter.$stateful = true;
return filter;
}])