The following works:
<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>
The word "Hello" on the screen flips between mixed case and upper-case when you press the button.
But Angular doesn't "know" it is supposed to re-invoke the filter function. It just does so because the click restarts the digest look and it re-does everything.
My question: is that behavior guaranteed? Can I always assume that the filter will be reinvoked in the digest loop and I can use whatever data in any scope I can find? Or did I just get lucky?
My secondary question: if the filter function is reinvoked on every digest loop, is there some way I can defeat that behavior? Can I tell it, unless the arguments have changed, don't call this function again, you'll just get the same answer? Or do I have to memoize by hand?
According to the angular docs, if you want to guarantee your filter to work you need to mark it as "stateful" using the $stateful
property of the filter.
It is strongly discouraged to write filters that are stateful, because the execution of those can't be optimized by Angular, which often leads to performance issues. Many stateful filters can be converted into stateless filters just by exposing the hidden state as a model and turning it into an argument for the filter.
If you however do need to write a stateful filter, you have to mark the filter as $stateful, which means that it will be executed one or more times during the each $digest cycle.
So you should mark your filter as stateful to guarantee that behavior:
.filter('myFilter', ['$rootScope', function($rootScope) {
var filter = function(v) {
return $rootScope.capitalize ? (v && v.toUpperCase()) : v;
};
filter.$stateful = true;
return filter;
}])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With