過濾器將表達(dá)式的運(yùn)算結(jié)果格式化后呈現(xiàn)給用戶,可以用于視圖模版,控制器或者服務(wù)。angularjs有一些內(nèi)置的過濾器,如果想自己自定義也很容易。
過濾器可以用于視圖模版中的表達(dá)式,語(yǔ)法如下:
{{ exPRession | filter }}例如,{{ 12 | currency }}
將數(shù)字12用currency過濾器格式化為貨幣輸出,最后的結(jié)果為$12.00
。
angularjs的過濾器也支持過濾鏈,語(yǔ)法如下:
{{ expression | filter1 | filter2 | ... }}過濾器還能支持參數(shù)輸入,語(yǔ)法如下:
{{ expression | filter:argument1:argument2:... }}例如{{ 1234 | number:2 }}
會(huì)將數(shù)字1234用number過濾器格式化,根據(jù)參數(shù)保留小數(shù)點(diǎn)后2位,結(jié)果為 1,234.00
視圖模版中的過濾器僅僅在輸入改變時(shí)才會(huì)執(zhí)行,這比每一次$digest循環(huán)都執(zhí)行一次要高效的多。
但也有兩種例外的情況:
通常只在輸入是基礎(chǔ)類型的過濾器才會(huì)在輸入改變時(shí)菜執(zhí)行。如果過濾器對(duì)輸入是object的話,每次$digest過濾器都會(huì)執(zhí)行,因?yàn)橐O(jiān)測(cè)object是否改變會(huì)更耗性能。如果過濾器標(biāo)記為$stateful,那么也會(huì)在每次$digest都執(zhí)行。你也可以在控制器,服務(wù)和指令中使用過濾器。
為此,需要將過濾器以<filterName>Filter
的語(yǔ)法注入到相應(yīng)的controller/service/directive中。例如你想注入number
過濾器就是用numberFilter
,過濾器函數(shù)作為控制器的第一個(gè)參數(shù)注入,過濾器的參數(shù)作為控制器函數(shù)的第二個(gè)參數(shù)。
下面的例子所使用的過濾器叫做filter,這個(gè)過濾器接受一個(gè)數(shù)組,并根據(jù)過濾條件產(chǎn)生一個(gè)子數(shù)組。如果在視圖模版中表示的話,可以寫成{{ctrl.array | filter:'a'}}
,將會(huì)對(duì)數(shù)組以a為關(guān)鍵字進(jìn)行全文搜索。然而,如果在視圖模版中這樣做的話,它會(huì)在每次$digest都執(zhí)行過濾器,這會(huì)非常耗費(fèi)性能。因此下面的例子就將過濾器寫在了控制器中,只有在需要的時(shí)候才會(huì)調(diào)用(例如從后端load數(shù)據(jù),或者過濾器的表達(dá)式需要改變時(shí))
自定義一個(gè)過濾器也相當(dāng)容易,僅僅需要在module中注冊(cè)一個(gè)新的filter工廠函數(shù)。工廠函數(shù)會(huì)返回一個(gè)新的過濾器函數(shù),過濾器的輸入作為過濾器函數(shù)的第一個(gè)參數(shù),其他過濾器的參數(shù)作為過濾器函數(shù)的附加參數(shù)傳入。
過濾器函數(shù)是一個(gè)純函數(shù),這意味著給出相同的輸入?yún)?shù)總能得到相同的輸出結(jié)果,而不受外界狀態(tài)的影響(例如,angularjs的services)。根據(jù)這一點(diǎn),angularjs才能做到僅僅當(dāng)輸入變化時(shí)才去執(zhí)行一次過濾器。帶狀態(tài)帶過濾器也存在,但是非常低效。
過濾器的名字必須是有效的angularjs表達(dá)式標(biāo)識(shí)符,例如uppercase,orderBy。名字中不能帶有特殊字符,比如-
和.
都是不允許的,你可以用駱駝命名法(myappSubsectionFilterx
)或者下劃線代替(myapp_subsection_filterx
)。
下面的例子是一個(gè)反轉(zhuǎn)字符串的過濾器,并且根據(jù)參數(shù)可以選擇大小寫:
<!DOCTYPE html><html><head> <meta charset="uft-8"/> <title></title></head><script src="script/angular.min.js"></script><script> angular.module('myReverseFilterApp', []) .filter('reverse', function() { return function(input, uppercase) { input = input || ''; var out = ''; for (var i = 0; i < input.length; i++) { out = input.charAt(i) + out; } // conditional based on optional argument if (uppercase) { out = out.toUpperCase(); } return out; }; }) .controller('MyController', ['$scope', 'reverseFilter', function($scope, reverseFilter) { $scope.greeting = 'hello'; $scope.filteredGreeting = reverseFilter($scope.greeting); }]);</script><body ng-app="myReverseFilterApp"><div ng-controller="MyController"> <input ng-model="greeting" type="text"><br> No filter: {{greeting}}<br> Reverse: {{greeting|reverse}}<br> Reverse + uppercase: {{greeting|reverse:true}}<br> Reverse, filtered in controller: {{filteredGreeting}}<br></div></body></html>強(qiáng)烈建議不要寫有狀態(tài)的過濾器,因?yàn)閍ngularjs并不會(huì)對(duì)其做優(yōu)化,常常會(huì)導(dǎo)致性能問題。很多狀態(tài)過濾器可以通過暴露模型的狀態(tài)并把它作為過濾器的參數(shù)傳入,來達(dá)到改為不帶狀態(tài)的過濾器。
如果你非要寫一個(gè)帶狀態(tài)帶過濾器,記得把過濾器標(biāo)記為$stateful,這樣每次$digest循環(huán)都好執(zhí)行一次或多次過濾器。
<!DOCTYPE html><html><head> <meta charset="uft-8"/> <title></title></head><script src="script/angular.min.js"></script><script> 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: '*'});</script><body ng-app="myStatefulFilterApp"><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> Decorated: {{greeting | decorate}}<br></div></body></html>上面的例子轉(zhuǎn)化為無狀態(tài)過濾器:
<!DOCTYPE html><html><head> <meta charset="uft-8"/> <title></title></head><script src="script/angular.min.js"></script><script> angular.module('myStatelessFilterApp', []) .filter('decorate', function() { function decorateFilter(input,symbol) { return symbol + input + symbol; } decorateFilter.$stateful = true; return decorateFilter; }) .controller('MyController', ['$scope', function($scope) { $scope.greeting = 'hello'; $scope.symbol="*"; }]) .value('decoration', {symbol: '*'});</script><body ng-app="myStatelessFilterApp"><div ng-controller="MyController"> Input: <input ng-model="greeting" type="text"><br> Decoration: <input ng-model="symbol" type="text"><br> No filter: {{greeting}}<br> Decorated: {{greeting | decorate:symbol}}<br></div></body></html> 如果我的文章對(duì)您有幫助,請(qǐng)用支付寶打賞:
新聞熱點(diǎn)
疑難解答
圖片精選