Angularjs中使用Filters详解
Filter作用就是接收一个输入,通过某个规则进行处理,然后给用户返回处理后的结果。Filter可以用在模板、控制器、或者服务,同时也会很容易自定义一个Filter过滤器。
在模板中使用Filter
Filter可以用于在视图模板中使用一下语法表达式:
{{expression|filter}}
例如:格式{{12|currency}}是使用currency的filter用法,让数字12过滤为货币形式,结果是$12.00。
Filter可以应用到另一个过滤的结果中。这就是所谓的“chaining”,使用语法如下:
{{expression|filter1|filter2|...}}
Filter中可能需要参数。语法为:
{{expression|filter:argument1:argument2:...}}
例如:格式{{1234|number:2}}是使用number的filter用法,将数字1234过滤为有两位小数点的数字,结果为:1,234.00。
在controller、services、directives中使用filter
你可以在controller、services、directives中使用filter。
为此,你需要将依赖项名称注入到你的controller/service/directive中:filter;例如:一个过滤器是number,你就需要通过使用依赖注入numberFilter。注入的参数是一个函数,该函数将值作为第一个参数,然后用第二个参数来筛选参数。
下面的例子使用了叫做filter的Filter过滤器。这个filter可以在subarrays的基础上减少arrays。也可以应用在视图模板的标记,就像:{{ctrl.array|filter:'a'}},这将为‘a'做一个全文搜索。然而,在视图模板中使用filter将会重新对每一个filter过滤,如果数组比较大的会是加载多次的。
因此下面的例子直接调用在控制器中的filter。通过这个,控制器可以在需要是调用filter(例如:当后端数据加载时或者filter的表达式改变时)。
index.html:
<divng-controller="FilterControllerasctrl"> <div> Allentries: <spanng-repeat="entryinctrl.array">{{entry.name}}</span> </div> <div> Entriesthatcontainan"a": <spanng-repeat="entryinctrl.filteredArray">{{entry.name}}</span> </div> </div>
script.js:
angular.module('FilterInControllerModule',[]). controller('FilterController',['filterFilter',function(filterFilter){ this.array=[ {name:'Tobias'}, {name:'Jeff'}, {name:'Brian'}, {name:'Igor'}, {name:'James'}, {name:'Brad'} ]; this.filteredArray=filterFilter(this.array,'a'); }]);
结果为:
Allentries:TobiasJeffBrianIgorJamesBrad Entriesthatcontainan"a":TobiasBrianJamesBrad
创建自定义filters:
编写自己的filter是非常简单的:只需要在你的模块中注册一个新的filterfactory函数。在内部,这里用了filterProvider。这个factory函数应该返回一个新的filter函数并且将输入值作为第一个参数。任何过滤器参数都会作为附加参数传递到过滤器函数中。
这个过滤器函数应该是一个单纯的函数。这意味着它应该stateless和idempotent。当输入的函数变化时,angular依赖这些属性并且执行filter。
注意:filter的名称必须是有效的angular表达式标识符。例如uppercase或者orderBy。名字是不允许有特殊的字符,如连字符和点是不允许的。如果你希望你的过滤器有名称空间,那么你可以使用大写(myappSubsectionFilterx)或者下划线(myapp_subsection_filterx)。
下面的示例filter是反写一个字符串。另外,它可以再加一个条件使字符串大写。
index.html
<divng-controller="MyController"> <inputng-model="greeting"type="text"><br> Nofilter:{{greeting}}<br> Reverse:{{greeting|reverse}}<br> Reverse+uppercase:{{greeting|reverse:true}}<br> Reverse,filteredincontroller:{{filteredGreeting}}<br> </div>
script.js
angular.module('myReverseFilterApp',[]) .filter('reverse',function(){ returnfunction(input,uppercase){ input=input||''; varout=""; for(vari=0;i<input.length;i++){ out=input.charAt(i)+out; } //conditionalbasedonoptionalargument if(uppercase){ out=out.toUpperCase(); } returnout; }; }) .controller('MyController',['$scope','reverseFilter',function($scope,reverseFilter){ $scope.greeting='hello'; $scope.filteredGreeting=reverseFilter($scope.greeting); }]);
结果为:
Nofilter:hello Reverse:olleh Reverse+uppercase:OLLEH Reverse,filteredincontroller:olleh
有状态的filters(Statefulfilters)
强烈建议写有状态的filters,因为这些不能用angular进行优化,这往往会导致性能问题。许多有状态的filters转换成无状态的filters仅仅通过揭露隐藏的状态作为model,并且将其转化为一个filter参数。
然而,如果你需要写一个有状态的filters,你必须将filter标记为$stateful,这也就意味着它将在每一个$digest周期内执行一次或多次。
index,html
<divng-controller="MyController"> Input:<inputng-model="greeting"type="text"><br> Decoration:<inputng-model="decoration.symbol"type="text"><br> Nofilter:{{greeting}}<br> Decorated:{{greeting|decorate}}<br> </div>
script.js:
angular.module('myStatefulFilterApp',[]) .filter('decorate',['decoration',function(decoration){ functiondecorateFilter(input){ returndecoration.symbol+input+decoration.symbol; } decorateFilter.$stateful=true; returndecorateFilter; }]) .controller('MyController',['$scope','decoration',function($scope,decoration){ $scope.greeting='hello'; $scope.decoration=decoration; }]) .value('decoration',{symbol:'*'});
结果为:
Nofilter:hello Decorated:*hello*
下次会写一篇angularjs中filter的常用用法。