Skip to content

Commit

Permalink
docs(guide/filters): add a note about $stateful flag and stateful fil…
Browse files Browse the repository at this point in the history
…ters
  • Loading branch information
IgorMinar committed Sep 16, 2014
1 parent 76741a9 commit 7c60264
Showing 1 changed file with 49 additions and 4 deletions.
53 changes: 49 additions & 4 deletions docs/content/guide/filter.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,16 @@ This factory function should return a new filter function which takes the input
as the first argument. Any filter arguments are passed in as additional arguments to the filter
function.

The filter function should be a [pure function](http://en.wikipedia.org/wiki/Pure_function), which
means that it should be stateless and idempotent. Angular relies on these properties and executes
the filter only when the inputs to the function change.

The following sample filter reverses a text string. In addition, it conditionally makes the
text upper-case.

<example module="myReverseModule">
<example module="myReverseFilterApp">
<file name="index.html">
<div ng-controller="Controller">
<div ng-controller="MyController">
<input ng-model="greeting" type="text"><br>
No filter: {{greeting}}<br>
Reverse: {{greeting|reverse}}<br>
Expand All @@ -101,7 +105,7 @@ text upper-case.
</file>

<file name="script.js">
angular.module('myReverseModule', [])
angular.module('myReverseFilterApp', [])
.filter('reverse', function() {
return function(input, uppercase) {
input = input || '';
Expand All @@ -116,12 +120,53 @@ text upper-case.
return out;
};
})
.controller('Controller', ['$scope', function($scope) {
.controller('MyController', ['$scope', function($scope) {
$scope.greeting = 'hello';
}]);
</file>
</example>


## Stateful filters

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.

<example module="myStatefulFilterApp">
<file name="index.html">
<div ng-controller="MyController">
Input: <input ng-model="greeting" type="text"><br>
Decoration: <input ng-model="decoration.symbol" type="text"><br>
No filter: {{greeting}}<br>
Reverse: {{greeting | decorate}}<br>
</div>
</file>

<file name="script.js">
angular.module('myStatefulFilterApp', [])
.filter('decorate', ['decoration', function(decoration) {

function decorateFilter(input) {
return decoration.symbol + input + decoration.symbol;
}
decorateFilter.$stateful = true;

return decorateFilter;
}])
.controller('MyController', ['$scope', 'decoration', function($scope, decoration) {
$scope.greeting = 'hello';
$scope.decoration = decoration;
}])
.value('decoration', {symbol: '*'});
</file>
</example>


## Testing custom filters

See the [phonecat tutorial](http://docs.angularjs.org/tutorial/step_09#test) for an example.

0 comments on commit 7c60264

Please sign in to comment.