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

    结果: (不影响视图)

  • 相关阅读:
    【CodeVS 3290】【NOIP 2013】华容道
    【UOJ #20】【NOIP 2014】解方程
    【UOJ #17】【NOIP 2014】飞扬的小鸟
    【UOJ #147】【NOIP 2015】斗地主
    【UOJ #150】【NOIP 2015】运输计划
    【POJ 3241】Object Clustering 曼哈顿距离最小生成树
    【COGS 254】【POI 2001】交通网络图
    【CodeVS 2083】Cryptcowgraphy 解密牛语
    1654 方程的解
    2124: 等差子序列
  • 原文地址:https://www.cnblogs.com/liulangmao/p/4026370.html
Copyright © 2020-2023  润新知