angular內置過濾器-filter


這篇文章來講解一下angular內置的filter過濾器.

沒錯,這個過濾器的名字,就叫'filter',雖然自定義過濾器也是使用module.filter()...但是不要混淆了,這個filter就是過濾器的名字~

這個過濾器是干嘛的呢? 它的作用是: '從數組中過濾出需要的項,放入新的數組並返回這個新數組。'

一.用在html模板里:

因為是用來過濾數組,所以這個過濾器基本上都用在ng-repeat指令上,比如:

<div ng-repeat="list in lists | filter : expression : comparator"></div>

filter過濾器會對lists數組進行過濾返回一個新的數組,過濾的方式取決於后面兩個參數: expression : comparator

*在最早的angular版本中,是沒有第二個參數的.

本篇的例子都是基於下面這段html和js的:

可以在這里輸入各個例子的代碼進行調試,查看結果:

http://jsfiddle.net/fxgzxuou/

<!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改為一個自定義函數,使得屬性值為''的情況一樣能夠被過濾出來:

http://jsfiddle.net/m0x9fn0z/

核心代碼:

    $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);

結果: (不影響視圖)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM