@@ -87,12 +87,16 @@ This factory function should return a new filter function which takes the input
87
87
as the first argument. Any filter arguments are passed in as additional arguments to the filter
88
88
function.
89
89
90
+ The filter function should be a [pure function](http://en.wikipedia.org/wiki/Pure_function), which
91
+ means that it should be stateless and idempotent. Angular relies on these properties and executes
92
+ the filter only when the inputs to the function change.
93
+
90
94
The following sample filter reverses a text string. In addition, it conditionally makes the
91
95
text upper-case.
92
96
93
- <example module="myReverseModule ">
97
+ <example module="myReverseFilterApp ">
94
98
<file name="index.html">
95
- <div ng-controller="Controller ">
99
+ <div ng-controller="MyController ">
96
100
<input ng-model="greeting" type="text"><br>
97
101
No filter: {{greeting}}<br>
98
102
Reverse: {{greeting|reverse}}<br>
@@ -101,7 +105,7 @@ text upper-case.
101
105
</file>
102
106
103
107
<file name="script.js">
104
- angular.module('myReverseModule ', [])
108
+ angular.module('myReverseFilterApp ', [])
105
109
.filter('reverse', function() {
106
110
return function(input, uppercase) {
107
111
input = input || '';
@@ -116,12 +120,53 @@ text upper-case.
116
120
return out;
117
121
};
118
122
})
119
- .controller('Controller ', ['$scope', function($scope) {
123
+ .controller('MyController ', ['$scope', function($scope) {
120
124
$scope.greeting = 'hello';
121
125
}]);
122
126
</file>
123
127
</example>
124
128
129
+
130
+ ## Stateful filters
131
+
132
+ It is strongly discouraged to write filters that are stateful, because the execution of those can't
133
+ be optimized by Angular, which often leads to performance issues. Many stateful filters can be
134
+ converted into stateless filters just by exposing the hidden state as a model and turning it into an
135
+ argument for the filter.
136
+
137
+ If you however do need to write a stateful filter, you have to mark the filter as `$stateful`, which
138
+ means that it will be executed one or more times during the each `$digest` cycle.
139
+
140
+ <example module="myStatefulFilterApp">
141
+ <file name="index.html">
142
+ <div ng-controller="MyController">
143
+ Input: <input ng-model="greeting" type="text"><br>
144
+ Decoration: <input ng-model="decoration.symbol" type="text"><br>
145
+ No filter: {{greeting}}<br>
146
+ Reverse: {{greeting | decorate}}<br>
147
+ </div>
148
+ </file>
149
+
150
+ <file name="script.js">
151
+ angular.module('myStatefulFilterApp', [])
152
+ .filter('decorate', ['decoration', function(decoration) {
153
+
154
+ function decorateFilter(input) {
155
+ return decoration.symbol + input + decoration.symbol;
156
+ }
157
+ decorateFilter.$stateful = true;
158
+
159
+ return decorateFilter;
160
+ }])
161
+ .controller('MyController', ['$scope', 'decoration', function($scope, decoration) {
162
+ $scope.greeting = 'hello';
163
+ $scope.decoration = decoration;
164
+ }])
165
+ .value('decoration', {symbol: '*'});
166
+ </file>
167
+ </example>
168
+
169
+
125
170
## Testing custom filters
126
171
127
172
See the [phonecat tutorial](http://docs.angularjs.org/tutorial/step_09#test) for an example.
0 commit comments