這篇文章來說解一下angular內置的filter過濾器.css
沒錯,這個過濾器的名字,就叫'filter',雖然自定義過濾器也是使用module.filter()...可是不要混淆了,這個filter就是過濾器的名字~html
這個過濾器是幹嗎的呢? 它的做用是: '從數組中過濾出須要的項,放入新的數組並返回這個新數組。'express
一.用在html模板裏:json
由於是用來過濾數組,因此這個過濾器基本上都用在ng-repeat指令上,好比:api
<div ng-repeat="list in lists | filter : expression : comparator"></div>
filter過濾器會對lists數組進行過濾返回一個新的數組,過濾的方式取決於後面兩個參數: expression : comparator數組
*在最先的angular版本中,是沒有第二個參數的.app
本篇的例子都是基於下面這段html和js的:函數
能夠在這裏輸入各個例子的代碼進行調試,查看結果:spa
http://jsfiddle.net/fxgzxuou/.net
<!DOCTYPE html> <html ng-app="app"> <head> <title>filter過濾器</title> <meta charset="utf-8"> <script src="../../angular.min.js"></script> <style type="text/css"> * { font-family:'MICROSOFT YAHEI' } b { font-weight:normal; color:#169FE7; } </style> </head> <body > <div ng-controller="ctrl"> <ul> <li ng-repeat="list in lists|filter:condition:mode"> <span><b>name:</b>{{list.name}}</span> <br/> <span><b>age:</b>{{list.age}}</span> </li> </ul> </div> </body>
</html>
var app = angular.module('app',[]); app.controller('ctrl',function($scope,$filter){ $scope.lists = [ {name:'code_bunny',age:12}, {name:'code_dog',age:3}, {name:'code_cat',age:22}, {name:'white_bunny_1',age:11}, {name:'white_bunny_2',age:11}, {name:'black_bunny',age:9}, {name:'mi_bunny_1',age:2}, {name:'mi_bunny_2',age:10}, {name:'mi_bunny_2',age:1} ];
//在這裏定義$scope.condition和$scope.mode })
在ctrl控制器下,有lists這樣一組數組,在後面咱們會經過改變參數condition和mode,來改變過濾條件,並觀察結果.在沒有任何過濾條件的時候,它所有顯示:
1.expression:
(1).字符串: 遍歷數組每一個對象的全部屬性,凡屬性中包含了expression字符串的,則這個對象被過濾出來.不區分大小寫.
eg 1.1.0:
/*普通模式,第三個參數爲false:*/ $scope.mode=false; //1.一個字符串:匹配屬性中帶有這個字符串的內容 $scope.condition='1';
結果: 將全部name屬性或者age屬性中帶有'1'的項都過濾出來了:
(2).json對象:
讓json對象裏的屬性值和數組中的屬性值一一對比過濾,過濾的規則仍是是否包含.好比 {name:"M", phone:"1"} 對象,會過濾出name屬性值中帶有M的,而且phone屬性值中帶有1的對象.
另外,{$:''}這個$屬性,表示過濾任何屬性.當使用{$:'1'}的時候,就至關於使用字符串'1'
eg 1.2.0:
/*普通模式,第三個參數爲false:*/ $scope.mode=false; //2.一個對象: 至關於$scope.condition='1'; $scope.condition={$:'1'};
結果:(和$scope.condition='1'的時候同樣)
eg 1.2.1:
/*普通模式,第三個參數爲false:*/ $scope.mode=false; //3.一個對象: 匹配name屬性值中帶有1的 $scope.condition={name:'1'};
結果: (過濾出name屬性中帶有'1'的項)
eg 1.2.2:
/*普通模式,第三個參數爲false:*/ $scope.mode=false; //4.一個對象: 匹配name屬性值中帶有bunny,age屬性值中帶有1的 $scope.condition={name:'bunny',age:1};
結果: (過濾出name屬性值中帶有bunny,age屬性值中帶有1的)
(3).函數:
function(value){...}
數組中的每一項都會被做爲函數的參數value傳入,而後執行這個函數,根據返回值來判斷是否被過濾.
eg 1.3.0: 過濾出name屬性值中既有m,又有b的(不必定要mb連在一塊兒)
$scope.mode=false; /*匹配一個函數*/ $scope.condition = function(value){ if(value.name.indexOf('m')>=0 && value.name.indexOf('b')>=0){ return true } };
結果:
*在這種狀況下,既然已經本身定義了過濾的模式,就沒有必要再定義第三個參數了.
2.comparator:
(1)true:嚴格匹配,不是匹配屬性值是否包含了過濾條件,而是必須===全等,大小寫也嚴格區分.
eg 2.1.0: 在eg1.1.0的基礎上,把第三個參數mode改成true:
/*嚴格模式,第三個參數爲true:*/ $scope.mode=true; //一個字符串:匹配屬性==='1' $scope.condition='1';
結果是空,由於嚴格過濾是===匹配,因此,數值1不==='1',
改爲:
/*嚴格模式,第三個參數爲true:*/ $scope.mode=true; //一個字符串:匹配屬性===1 $scope.condition=1;
結果:
eg 2.1.1: 在eg1.2.0的基礎上,把第三個參數mode改成true,而且把'1'改成1:
/*嚴格模式,第三個參數爲true*/ $scope.mode=true; //6.嚴格匹配對象: 匹配屬性值===1的 $scope.condition={$:1};
結果同eg 2.1.0
eg 2.1.2:
/*嚴格模式,第三個參數爲true*/ $scope.mode=true; //7.嚴格匹配對象: name值==='white_bunny_1',age值===11的 $scope.condition={name:'white_bunny_1',age:11};
結果:
(2)函數:
function(actual,expected){ //actual是對象實際的值 //expected是過濾條件的值
return ... }
這個函數是用來本身定義過濾的模式的,以前已經說過,若是不定義第二個參數,那麼它是按照'是否包含'來進行過濾的,若是第二個參數是true, 那麼它是按照'是否全等'來進行過濾的.而自定義函數,則是按照自定義的規則來進行過濾.
函數接受兩個參數:
actual:對象的實際屬性值
expected:第一個參數中定義的過濾條件值
eg 2.2.0:
//9.深度匹配對象:{name:'mi_bunny_1',age:'10'} //要求過濾的方式是比較是否相等,但不比較數據格式.好比這裏的'10'==10,能夠被過濾出來 $scope.mode=function(actual,expected){ if(actual==expected){ return true } }; $scope.condition={name:'mi_bunny_2',age:'10'};
結果:
這裏自定義了一個過濾方式,是比較是否相等,而不是是否全等,屬性值的格式能夠不一樣.
eg 2.2.1:
//10.深度匹配字符串:'11':匹配年齡或者name==11的 $scope.mode=function(actual,expected){ if(actual==expected){ return true } }; $scope.condition='11';
結果:
過濾條件改爲'11',同樣遵循這個函數的過濾方式
*注意,經過第二個參數自定義函數來自定義過濾條件,它定義的過濾條件是針對全部的屬性的,不能爲各個屬性指定本身的過濾方式,若是是要爲某個屬性自定義過濾方法,應該使用第一個參數的函數形式,相似於eg1.3.0
eg 2.2.2:
在filter的官方api裏有一個這樣的demo:
http://www.ngnice.com/docs/api/ng/filter/filter
Any: <input ng-model="search.$"> <br> Name only <input ng-model="search.name"><br> Phone only <input ng-model="search.phone"><br> Equality <input type="checkbox" ng-model="strict"><br> <table id="searchObjResults"> <tr><th>Name</th><th>Phone</th></tr> <tr ng-repeat="friendObj in friends | filter:search:strict"> <td>{{friendObj.name}}</td> <td>{{friendObj.phone}}</td> </tr> </table>
這個demo使用的是嚴格過濾模式,也就是第二個參數是true,可是這樣會出現一種bug:
一開始沒有輸入Name only和Phone only的時候,search.name和search.phone是沒有的,不是說{name:'',phone:''},而是{}就是空的,
因此當只輸入name項之後變爲{name:'John'},這個時候能夠匹配到name值爲John的數據,而後我phone項後變爲{name:'John',phone:'555-1276'},也是能夠匹配到正確的數據的.
可是,當我清空phone之後,它會變爲{name:'John',phone:''},因此數據中就再也不有可以匹配到的項了.因此,這個例子,一旦輸入過某項再清空,就沒法再正確使用嚴格模式來匹配數據了.
因此,我將第三個參數true改成一個自定義函數,使得屬性值爲''的狀況同樣可以被過濾出來:
核心代碼:
$scope.mode = function(actual,expected){ if(actual===expected || expected==''){ return true } else { return false } }
(3)false || undefined: 默認狀況,沒有第三個參數,不進行嚴格匹配
二.直接在js裏使用,須要注入$filter依賴:
var newArry = $filter('filter')(array, expression, comparator)
第一個參數array就是須要被過濾的數組,後面兩個參數用法都同上.
eg 3.1.0:
//直接在js裏面使用: var newArray = $filter('filter')($scope.lists, 'black', false); console.log(newArray);
結果: (不影響視圖)