AngularJS 霸道的过滤器

来源:互联网 发布:ui设计 前景 知乎 编辑:程序博客网 时间:2024/05/16 01:38

学习要点

  • 为什么使用过滤器
  • 过滤单个数据的值
    • 格式化货币值
    • 格式化数字值
    • 格式化日期
    • 改变字符串大小写
    • 生成JSON
    • 本地化过滤器输出
  • 过滤集合
    • 限制项目数量
    • 选取项
    • 对项目排序
  • 链式过滤器
  • 自定义过滤器
    • 创建格式化数据值的过滤器
    • 创建集合过滤器
    • 在已有过滤器上搭建新的过滤器

一、为什么使用过滤器?
在实际操作中,我们需要对统一数据源进行多次转换,比如我的货币单位,在不同的国家我们将用不同的符号表示。因此,你可能会想到在控制器中判断国家以显示不同的结果,但是过滤器却可以更好的帮助我们做到同样的效果。
过滤器将数据在被指令处理并显示到视图之前进行转换,而不必修改作用域中原有的数据,这样能够允许同一份数据在应用中的不同部分以不同形式得以展示。
接下来,我们详细讨论有关过滤器的用法
GO….
二、过滤单个数据的值
下表展示用于单个数据的内置过滤器
这里写图片描述
先来看看我们的准备案例,待会我们将在这个案例的基础上来使用内容过滤器

<!DOCTYPE><!-- use module --><html ng-app="exampleApp"><head>    <title>Angluar test</title>    <meta charset="utf-8"/>    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css"></head><body>    <dlv class="panel panel-default" ng-controller="defaultCtrl">        <div class="panel panel-header">            Products            <span class="label label-primary">{{products.length}}</span>        </div>        <div class="panel panel-body">            <table class="table table-striped table-bordered table-hover">                <thead>                    <tr><th>Name</th><th>Category</th><th>Expiry</th><th>Price</th></tr>                </thead>                <tbody>                    <tr ng-repeat="p in products">                        <td>{{p.name}}</td>                        <td>{{p.category}}</td>                        <td>{{p.expiry}}</td>                        <td>{{p.price}}</td>                    </tr>                </tbody>            </table>        </div>    </dlv><script type="text/javascript" src="js/angular.min.js"></script><script type="text/javascript">var myApp = angular.module("exampleApp", []);myApp.controller("defaultCtrl", function ($scope) {    $scope.products = [        { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },        { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },        { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 },        { name: "Tuna", category: "Fish", price: 20.45, expiry: 3 },        { name: "Salmon", category: "Fish", price: 17.93, expiry: 2 },        { name: "Trout", category: "Fish", price: 12.93, expiry: 4 },        { name: "Beer", category: "Drinks", price: 2.99, expiry: 365 },        { name: "Wine", category: "Drinks", price: 8.99, expiry: 365 },        { name: "Whiskey", category: "Drinks", price: 45.99, expiry: 365 }    ];})</script></body></html>

就是一个表格的形式来展示产品的详细情况的案例
这里写图片描述

1.格式化货币值

<tr ng-repeat="p in products">    <td>{{p.name}}</td>    <td>{{p.category}}</td>    <td>{{p.expiry}}</td>    <!-- 使用currency -->    <td>{{p.price | currency}}</td></tr>

这里写图片描述

2.格式化数字值

<tr ng-repeat="p in products">    <td>{{p.name}}</td>    <td>{{p.category}}</td>    <td>{{p.expiry}}</td>    <!-- 保留小数点后3位 -->    <td>{{p.price | number : 3}}</td></tr>

这里写图片描述

3.格式化日期

// 在控制器中添加$scope.getExpiryDate = function (days) {    var now = new Date();    return now.setDate(now.getDate() + days);}
<tr ng-repeat="p in products">    <td>{{p.name}}</td>    <td>{{p.category}}</td>    <!-- 在视图中使用-->    <td>{{getExpiryDate(p.expiry) | date : 'yyyy/MM/dd'}}</td>    <!-- 货币单位本地化 -->    <td>{{p.price}}</td></tr>

这里写图片描述

4.改变字符串大小写

<tr ng-repeat="p in products">    <!-- 字母大小写 -->    <td>{{p.name | uppercase}}</td>    <td>{{p.category | lowercase}}</td>    <td>{{getExpiryDate(p.expiry) | date : 'yyyy/MM/dd'}}</td>    <!-- 货币单位本地化 -->    <td>{{p.price}}</td></tr>

这里写图片描述

5.生成JSON

<tr ng-repeat="p in products">    <!-- 生成JSON数据 -->    <td>{{p.name | json}}</td>    <td>{{p.category}}</td>    <td>{{getExpiryDate(p.expiry) | date : 'yyyy/MM/dd'}}</td>    <!-- 货币单位本地化 -->    <td>{{p.price}}</td></tr>

这里写图片描述

6.本地化过滤器输出
需要移入本地化JS文件

<!-- 引入本地化文件 --><script type="text/javascript" src="js/angular-locale_zh-cn.js"></script>
<tr ng-repeat="p in products">    <td>{{p.name}}</td>    <td>{{p.category}}</td>    <td>{{p.expiry}}</td>    <!-- 货币单位本地化 -->    <td>{{p.price | currency}}</td></tr>

这里写图片描述

三、过滤集合
1.限制项目的数量—limitTo过滤器

<!DOCTYPE><!-- use module --><html ng-app="exampleApp"><head>    <title>Angluar test</title>    <meta charset="utf-8"/>    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css"></head><body>    <dlv class="panel panel-default" ng-controller="defaultCtrl">        <div class="panel panel-header">            Products            <span class="label label-primary">{{products.length}}</span>        </div>        <div class="panel panel-body">            Limit: <select ng-model="limitVal" ng-options="item for item in limitRange"></select>        </div>        <div class="panel panel-body">            <table class="table table-striped table-bordered table-hover">                <thead>                    <tr><th>Name</th><th>Category</th><th>Expiry</th><th>Price</th></tr>                </thead>                <tbody>                    <!-- 只显示limitVal行 -->                    <tr ng-repeat="p in products | limitTo : limitVal">                        <td>{{p.name}}</td>                        <td>{{p.category}}</td>                        <td>{{p.expiry}}</td>                        <td>{{p.price | number : 2}}</td>                    </tr>                </tbody>            </table>        </div>    </dlv><script type="text/javascript" src="js/angular.min.js"></script><!-- 引入本地化文件 --><script type="text/javascript" src="js/angular-locale_zh-cn.js"></script><script type="text/javascript">var myApp = angular.module("exampleApp", []);myApp.controller("defaultCtrl", function ($scope) {    $scope.products = [        { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },        { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },        { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 },        { name: "Tuna", category: "Fish", price: 20.45, expiry: 3 },        { name: "Salmon", category: "Fish", price: 17.93, expiry: 2 },        { name: "Trout", category: "Fish", price: 12.93, expiry: 4 },        { name: "Beer", category: "Drinks", price: 2.99, expiry: 365 },        { name: "Wine", category: "Drinks", price: 8.99, expiry: 365 },        { name: "Whiskey", category: "Drinks", price: 45.99, expiry: 365 }    ];    // 显示的条数    $scope.limitVal = '5';    // 在限制条数的范围条项    $scope.limitRange = [];    for (var i = (0 - $scope.products.length); i <= $scope.products.length; i++) {        $scope.limitRange.push(i.toString());    }})</script></body></html>

单击下拉列表,根据提示显示不同的条数,负数表示从后往前取
这里写图片描述

2.选取项—filter过滤器

<!DOCTYPE><!-- use module --><html ng-app="exampleApp"><head>    <title>Angluar test</title>    <meta charset="utf-8"/>    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css"></head><body>    <dlv class="panel panel-default" ng-controller="defaultCtrl">        <div class="panel panel-header">            Products            <span class="label label-primary">{{products.length}}</span>        </div>        <div class="panel panel-body">            <table class="table table-striped table-bordered table-hover">                <thead>                    <tr><th>Name</th><th>Category</th><th>Expiry</th><th>Price</th></tr>                </thead>                <tbody>                    <!-- 自定义过滤 -->                    <tr ng-repeat="p in products | filter : selectItems">                        <td>{{p.name}}</td>                        <td>{{p.category}}</td>                        <td>{{p.expiry}}</td>                        <td>{{p.price | number : 2}}</td>                    </tr>                </tbody>            </table>        </div>    </dlv><script type="text/javascript" src="js/angular.min.js"></script><!-- 引入本地化文件 --><script type="text/javascript" src="js/angular-locale_zh-cn.js"></script><script type="text/javascript">var myApp = angular.module("exampleApp", []);myApp.controller("defaultCtrl", function ($scope) {    $scope.products = [        { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },        { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },        { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 },        { name: "Tuna", category: "Fish", price: 20.45, expiry: 3 },        { name: "Salmon", category: "Fish", price: 17.93, expiry: 2 },        { name: "Trout", category: "Fish", price: 12.93, expiry: 4 },        { name: "Beer", category: "Drinks", price: 2.99, expiry: 365 },        { name: "Wine", category: "Drinks", price: 8.99, expiry: 365 },        { name: "Whiskey", category: "Drinks", price: 45.99, expiry: 365 }    ];    // 自定义过滤器    $scope.selectItems = function (item) {        // 仅仅保留类别为Fish或者name=='Beer'的行        return item.category == 'Fish' || item.name == 'Beer';    }})</script></body></html>

仅仅保留类别为Fish或者name=='Beer'的行
这里写图片描述

3.对项目进行排序—orderBy过滤器

<!DOCTYPE><!-- use module --><html ng-app="exampleApp"><head>    <title>Angluar test</title>    <meta charset="utf-8"/>    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css"></head><body>    <dlv class="panel panel-default" ng-controller="defaultCtrl">        <div class="panel panel-header">            Products            <span class="label label-primary">{{products.length}}</span>        </div>        <div class="panel panel-body">            <table class="table table-striped table-bordered table-hover">                <thead>                    <tr><th>Name</th><th>Category</th><th>Expiry</th><th>Price</th></tr>                </thead>                <tbody>                    <!-- 通过价格按照升序排列 -->                    <!-- <tr ng-repeat="p in products | orderBy : 'price'"> -->                    <!-- price前加-表示按照降序排列 -->                    <!-- <tr ng-repeat="p in products | orderBy : '-price'"> -->                    <!-- 自定义排序 -->                    <!-- <tr ng-repeat="p in products | orderBy : customOrder"> -->                    <!-- 组合排序,保质期<5的降序排列,其他的按照价格升序排序 -->                    <tr ng-repeat="p in products | orderBy : [customOrder, '-price']">                        <td>{{p.name}}</td>                        <td>{{p.category}}</td>                        <td>{{p.expiry}}</td>                        <td>{{p.price | number : 2}}</td>                    </tr>                </tbody>            </table>        </div>    </dlv><script type="text/javascript" src="js/angular.min.js"></script><!-- 引入本地化文件 --><script type="text/javascript" src="js/angular-locale_zh-cn.js"></script><script type="text/javascript">var myApp = angular.module("exampleApp", []);myApp.controller("defaultCtrl", function ($scope) {    $scope.products = [        { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },        { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },        { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 },        { name: "Tuna", category: "Fish", price: 20.45, expiry: 3 },        { name: "Trout", category: "Fish", price: 12.93, expiry: 4 },        { name: "Salmon", category: "Fish", price: 17.93, expiry: 2 },        { name: "Beer", category: "Drinks", price: 2.99, expiry: 365 },        { name: "Wine", category: "Drinks", price: 8.99, expiry: 365 },        { name: "Whiskey", category: "Drinks", price: 45.99, expiry: 365 }    ];    // 自定义函数排序    $scope.customOrder = function (item) {        // 保质期<5的不排序,其他的按照价格升序排序        return item.expiry < 5 ? 0 : item.price;    }})</script></body></html>

保质期<5的不排序,其他的按照价格升序排序
这里写图片描述
四、链式过滤器
就是将过滤器串联起来综合使用

<!DOCTYPE><!-- use module --><html ng-app="exampleApp"><head>    <title>Angluar test</title>    <meta charset="utf-8"/>    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css"></head><body>    <dlv class="panel panel-default" ng-controller="defaultCtrl">        <div class="panel panel-header">            Products            <span class="label label-primary">{{products.length}}</span>        </div>        <div class="panel panel-body">            <table class="table table-striped table-bordered table-hover">                <thead>                    <tr><th>Name</th><th>Category</th><th>Expiry</th><th>Price</th></tr>                </thead>                <tbody>                    <!-- 过滤链条,通过orderBy和limitTo共同作用 -->                    <tr ng-repeat="p in products | orderBy : [customOrder, '-price'] | limitTo : 5">                        <td>{{p.name}}</td>                        <td>{{p.category}}</td>                        <td>{{p.expiry}}</td>                        <td>{{p.price | number : 2}}</td>                    </tr>                </tbody>            </table>        </div>    </dlv><script type="text/javascript" src="js/angular.min.js"></script><!-- 引入本地化文件 --><script type="text/javascript" src="js/angular-locale_zh-cn.js"></script><script type="text/javascript">var myApp = angular.module("exampleApp", []);myApp.controller("defaultCtrl", function ($scope) {    $scope.products = [        { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },        { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },        { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 },        { name: "Tuna", category: "Fish", price: 20.45, expiry: 3 },        { name: "Trout", category: "Fish", price: 12.93, expiry: 4 },        { name: "Salmon", category: "Fish", price: 17.93, expiry: 2 },        { name: "Beer", category: "Drinks", price: 2.99, expiry: 365 },        { name: "Wine", category: "Drinks", price: 8.99, expiry: 365 },        { name: "Whiskey", category: "Drinks", price: 45.99, expiry: 365 }    ];    // 自定义函数排序    $scope.customOrder = function (item) {        // 保质期<5的不排序,其他的按照价格升序排序        return item.expiry < 5 ? 0 : item.price;    }})</script></body></html>

先按照自定义customOrder函数以price倒序排列,然后只取得5条数据

<tr ng-repeat="p in products | orderBy : [customOrder, '-price'] | limitTo : 5">

这里写图片描述

五、自定义过滤器
1.创建格式化数据值的过滤器

<!DOCTYPE><!-- use module --><html ng-app="exampleApp"><head>    <title>Angluar test</title>    <meta charset="utf-8"/>    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">    <link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css"></head><body>    <dlv class="panel panel-default" ng-controller="defaultCtrl">        <div class="panel panel-header">            Products            <span class="label label-primary">{{products.length}}</span>        </div>        <div class="panel panel-body">            <table class="table table-striped table-bordered table-hover">                <thead>                    <tr><th>Name</th><th>Category</th><th>Expiry</th><th>Price</th></tr>                </thead>                <tbody>                    <tr ng-repeat="p in products">                        <!-- 使用自定义过滤器 -->                        <td>{{p.name | labelCase}}</td>                        <td>{{p.category | labelCase : true}}</td>                        <td>{{p.expiry}}</td>                        <td>{{p.price | number : 2}}</td>                    </tr>                </tbody>            </table>        </div>    </dlv><script type="text/javascript" src="js/angular.min.js"></script><script type="text/javascript">var myApp = angular.module("exampleApp", []);myApp.controller("defaultCtrl", function ($scope) {    $scope.products = [        { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },        { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },        { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 },        { name: "Tuna", category: "Fish", price: 20.45, expiry: 3 },        { name: "Trout", category: "Fish", price: 12.93, expiry: 4 },        { name: "Salmon", category: "Fish", price: 17.93, expiry: 2 },        { name: "Beer", category: "Drinks", price: 2.99, expiry: 365 },        { name: "Wine", category: "Drinks", price: 8.99, expiry: 365 },        { name: "Whiskey", category: "Drinks", price: 45.99, expiry: 365 }    ];});</script><!-- 引入自定义的过滤器 --><script type="text/javascript" src="js/createFilters.js"></script></body></html>

自定义过滤器,labelCase反转字符串

// js/createFilters.js文件angular.module("exampleApp")    .filter("labelCase", function () {        return function (value, reverse) {            if (angular.isString(value)) {                var inter = reverse ? value.toUpperCase() : value.toLowerCase();                return (reverse ? inter[0].toLowerCase() : inter[0].toUpperCase()) + inter.substr(1);            } else {                return value;            }        }    })

这里写图片描述
2.创建集合过滤器
在createFilter中定义一个skip过滤函数

angular.module("exampleApp")    .filter("labelCase", function () {        return function (value, reverse) {            if (angular.isString(value)) {                var inter = reverse ? value.toUpperCase() : value.toLowerCase();                return (reverse ? inter[0].toLowerCase() : inter[0].toUpperCase()) + inter.substr(1);            } else {                return value;            }        }    })    .filter("skip", function () {        return function (value, count) {            if (angular.isArray(value) && angular.isNumber(count)){                if (count > value.length || count < 0) {                    return value;                } else {                    // 跳过数组前两项                    return value.slice(count);                }            } else {                return value;            }        }    })

在视图中使用

<tr ng-repeat="p in products | skip : 2">    <!-- 使用自定义过滤器 -->    <td>{{p.name | labelCase}}</td>    <td>{{p.category | labelCase : true}}</td>    <td>{{p.expiry}}</td>    <td>{{p.price | number : 2}}</td></tr>

移除前两项Apples和Bananas,然后显示
这里写图片描述

3.在已有的过滤器上搭建新的过滤器
在createFilter中添加take过滤器返回,将skip和limitTo两个过滤器方法综合起来

angular.module("exampleApp")    .filter("labelCase", function () {        return function (value, reverse) {            if (angular.isString(value)) {                var inter = reverse ? value.toUpperCase() : value.toLowerCase();                return (reverse ? inter[0].toLowerCase() : inter[0].toUpperCase()) + inter.substr(1);            } else {                return value;            }        }    })    .filter("skip", function () {        return function (value, count) {            if (angular.isArray(value) && angular.isNumber(count)){                if (count > value.length || count < 0) {                    return value;                } else {                    // 跳过数组前两项                    return value.slice(count);                }            } else {                return value;            }        }    })    // 在已有过滤器的基础上建立新的过滤器    // 将上述的skip和limit两个过滤器合并    .filter("take", function ($filter) {        return function (data, skipCount, limitCount) {            // 先跳过数组的前skipCount项            var skipData = $filter("skip")(data, skipCount);            // 接着只取limitCount行            return $filter("limitTo")(skipData, limitCount);        }    })

在视图中使用:

<tr ng-repeat="p in products | take : 2 : 5"><!-- 使用自定义过滤器 -->    <td>{{p.name | labelCase}}</td>    <td>{{p.category | labelCase : true}}</td>    <td>{{p.expiry}}</td>    <td>{{p.price | number : 2}}</td></tr>

先移除两项,然后值取5条数据
这里写图片描述

1 0
原创粉丝点击