AngularJS 1.x系列:AngularJS過濾器(4)

libingql發表於2017-06-01

1. AngularJS過濾器(Filter)使用方法

  AngularJS中過濾器(Filter)主要功能是格式化資料。

  AngularJS過濾器使用方法有3種:

  ◊ 在表示式{{}}中使用

  ◊ 在指令中使用

  ◊ 在Controller或Service、Factory、Provider等服務中使用

1.1 表示式中使用過濾器

  過濾器使用管道符(|)新增到表示式或指令中。

  語法:

{{ expression | filter }}

  可以同時使用多個過濾器,多個過濾器之間管道符(|)分隔。

{{ expression | filter1 | filter2 | ... | filterN }}

  過濾器可以帶引數,引數使用冒號(:)隔開。

{{ expression | filter1:param1 | filter2:param2 | ... | filterN:paramN }}

1.2 指令中使用過濾器

  過濾器使用管道符(|)新增到表示式或指令中。

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <script src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("ProductCtrl", ["$scope", function($scope){
                $scope.data = [
                    { ProductName: "家電", Quantity: 600 },
                    { ProductName: "數碼", Quantity: 200 },
                    { ProductName: "手機", Quantity: 300 }
                ];
            }]);
        </script>
    </head>
    <body>
        <ul ng-controller="ProductCtrl">
            <li ng-repeat="item in data | orderBy: 'Quantity'">
                <span>{{ item.ProductName }}</span>
                <span>{{ item.Quantity }}</span>
            </li>
        </ul>
    </body>
</html>

  降序:

<li ng-repeat="item in data | orderBy: 'Quantity' : true">

1.3 在Controller或AngularJS服務中使用過濾器

  在Controller、Service、Factory、Provider等服務中使用過濾器方式:依賴注入

  示例:

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("MainCtrl", ["$scope", "currencyFilter", function($scope, currencyFilter) {
                $scope.unitprice = currencyFilter(10000);
            }]);
        </script>
    </head>
    <body>
        <div ng-controller="MainCtrl">
            {{ unitprice }}
        </div>
    </body>
</html>

  currencyFilter為AngularJS內建過濾器,用於將數字轉化為貨幣形式。

  AngularJS提供$filter服務,可以呼叫所有過濾器。

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("MainCtrl", ["$scope", "$filter", function($scope, $filter) {
                $scope.unitprice = $filter("currency")(10000);
                $scope.now = $filter("date")(new Date(), "yyyy-MM-dd HH:mm:ss");
            }]);
        </script>
    </head>
    <body>
        <div ng-controller="MainCtrl">
            {{ unitprice }}  // $10,000.00
            {{ now }}        // 2017-06-05 23:08:02
        </div>
    </body>
</html>
$scope.unitprice = $filter("currency")(10000, "");  // ¥10,000.00

  $filter("name")根據名稱獲取對應的過濾器,把資料作為引數傳遞給過濾器處理。

2. AngularJS內建過濾器

2.1 filter

  filter過濾器用來處理陣列,過濾包含某個子串的元素,過濾後的元素作為子陣列返回。可以是字串陣列或物件陣列。

  物件陣列,則匹配屬性的值。可以接收一個引數,用來定義子元素的匹配規則。

  示例:

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("ProductCtrl", ["$scope", function($scope){
                $scope.data = [
                    { ProductName: "家電", Quantity: 1000, UnitPrice: 100 },
                    { ProductName: "數碼", Quantity: 2000, UnitPrice: 200 },
                    { ProductName: "手機", Quantity: 3000, UnitPrice: 300 }
                ];
            }]);
        </script>
    </head>
    <body>
        <div class="container">
            <div class="row">
                <input type="text" class="form-control" ng-model="keyword" placeholder="請輸入查詢關鍵字" />
            </div>
            <table class="table table-bordered table-hover" ng-controller="ProductCtrl">
                <thead>
                    <tr>
                        <th class="text-center">商品名稱</th>
                        <th class="text-center">數量</th>
                        <th class="text-center">單價</th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="item in data | filter: keyword">
                        <td>{{ item.ProductName }}</td>
                        <td class="text-center">{{ item.Quantity }}</td>
                        <td class="text-center">{{ item.UnitPrice }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("ProductCtrl", ["$scope", function($scope){
                $scope.data = [
                    { ProductName: "家電", Quantity: 1000, UnitPrice: 100 },
                    { ProductName: "數碼", Quantity: 2000, UnitPrice: 200 },
                    { ProductName: "手機", Quantity: 3000, UnitPrice: 300 }
                ];
            }]);
        </script>
    </head>
    <body>
        <div class="container">
            <table class="table table-bordered table-hover" ng-controller="ProductCtrl">
                <thead>
                    <tr>
                        <th class="text-center">商品名稱</th>
                        <th class="text-center">數量</th>
                        <th class="text-center">單價</th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="item in data | filter: {'ProductName': '數'}">
                        <td>{{ item.ProductName }}</td>
                        <td class="text-center">{{ item.Quantity }}</td>
                        <td class="text-center">{{ item.UnitPrice | currency }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

2.2 currency

  currency貨幣格式化,預設為$,可以引數設定其他符號及精度。

  示例:

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("ProductCtrl", ["$scope", function($scope){
                $scope.data = [
                    { ProductName: "家電", Quantity: 1000, UnitPrice: 100 },
                    { ProductName: "數碼", Quantity: 2000, UnitPrice: 200 },
                    { ProductName: "手機", Quantity: 3000, UnitPrice: 300 }
                ];
            }]);
        </script>
    </head>
    <body>
        <div class="container">
            <div class="row">
                <input type="text" class="form-control" ng-model="keyword" placeholder="請輸入查詢關鍵字" />
            </div>
            <table class="table table-bordered table-hover" ng-controller="ProductCtrl">
                <thead>
                    <tr>
                        <th class="text-center">商品名稱</th>
                        <th class="text-center">數量</th>
                        <th class="text-center">單價</th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="item in data | filter: keyword">
                        <td>{{ item.ProductName }}</td>
                        <td class="text-center">{{ item.Quantity }}</td>
                        <td class="text-center">{{ item.UnitPrice | currency }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

  設定其他符號:

{{ 1000 | currency: "¥" }}   // ¥1,000.00

  設定精度:

{{ 1000.75 | currency: "¥": 1 }}  // ¥1,000.8

2.3 number

  number過濾器用於將數字格式化為文字,可以對數字設定精度。預設保留的小數位數小於或等於3。

{{ 10000 | number }}  // 10,000
{{ 3.1415926 | number }}   // 3.142
{{ 3.1415926 | number: 2 }}  // 3.14

2.4 lowercase & uppercase

  lowercase過濾器:將字串中的大寫字母全部轉換為小寫。

{{ "Hello AngularJS" | lowercase }}  // hello angularjs

  uppercase過濾器:將字串中的小寫字母全部轉換為大寫。

{{ "Hello AngularJS" | uppercase }}  // HELLO ANGULARJS

2.5 date

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("DateCtrl", ["$scope", function($scope){
                $scope.now = new Date();
            }]);
        </script>
    </head>
    <body>
        <div ng-controller="DateCtrl">
           <span>{{ now | date }}</span>
           <span>{{ now | date: "yyyy-MM-dd" }}</span>
           <span>{{ now | date: "yyyy-MM-dd HH:mm:ss" }}</span>
           <span>{{ now | date: "yyyy年MM月dd日" }}</span>
        </div>
    </body>
</html>

2.5 limitTo

  limitTo過濾器:用來擷取陣列或字串,引數用來指定截圖長度。如果引數是負值,則從尾部開始擷取。

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("ProductCtrl", ["$scope", function($scope){
                $scope.data = [
                    { ProductName: "家電", Quantity: 1000, UnitPrice: 100 },
                    { ProductName: "數碼", Quantity: 2000, UnitPrice: 200 },
                    { ProductName: "手機", Quantity: 3000, UnitPrice: 300 }
                ];
            }]);
        </script>
    </head>
    <body>
        <div class="container">
            <table class="table table-bordered table-hover" ng-controller="ProductCtrl">
                <thead>
                    <tr>
                        <th class="text-center">商品名稱</th>
                        <th class="text-center">數量</th>
                        <th class="text-center">單價</th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="item in data | limitTo: 2">
                        <td>{{ item.ProductName }}</td>
                        <td class="text-center">{{ item.Quantity }}</td>
                        <td class="text-center">{{ item.UnitPrice | currency }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

{{ "Hello" | limitTo: 2 }}  // He

2.6 orderBy

  orderBy過濾器:用來將一個陣列中的元素進行排序,可以設定引數指定排序規則。

  引數:字串,表示按照該屬性名進行排序。

  引數:陣列,表示依次按照陣列中的屬性進行排序。

  示例:

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("ProductCtrl", ["$scope", function($scope){
                $scope.data = [
                    { ProductName: "家電", Quantity: 5000, UnitPrice: 500 },
                    { ProductName: "數碼", Quantity: 2000, UnitPrice: 200 },
                    { ProductName: "手機", Quantity: 3000, UnitPrice: 300 }
                ];
            }]);
        </script>
    </head>
    <body>
        <div class="container">
            <table class="table table-bordered table-hover" ng-controller="ProductCtrl">
                <thead>
                    <tr>
                        <th class="text-center">商品名稱</th>
                        <th class="text-center">數量</th>
                        <th class="text-center">單價</th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="item in data | orderBy: 'Quantity' | limitTo: 2">
                        <td>{{ item.ProductName }}</td>
                        <td class="text-center">{{ item.Quantity }}</td>
                        <td class="text-center">{{ item.UnitPrice | currency }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

  orderBy過濾器預設為升序。

  設定降序兩種方式:

<tr ng-repeat="item in data | orderBy: 'Quantity': true | limitTo: 2">
<tr ng-repeat="item in data | orderBy: '-Quantity' | limitTo: 2">  // 排序屬性前加減號(-)

3. 自定義過濾器

  AngularJS自定義過濾器,呼叫模組例項的filter()方法。

3.1 自定義不帶引數過濾器

  filter()使用方法:

var app = angular.module("app", []);
app.filter("filterName", function() {
    return function(input) {
        // 邏輯處理
        ...
        return result;
    };
});

  filter()方法兩個引數:

    第一個引數:過濾器名稱,

    第二個引數:過濾器定義方法,必須返回一個用於處理過濾器邏輯的方法。返回的方法可接受一個引數:過濾器的輸出資料。

  示例:

<!DOCTYPE html>
<html ng-app="app">
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
    <script type="text/javascript" src="../lib/angular.min.js"></script>
    <script type="text/javascript">
        var app = angular.module("app", []);
        app.controller("MainCtrl", ["$scope", function ($scope) {
            $scope.amount = 1234.53;
        }]);
        app.filter("toRMB", function () {
            return function (input) {
                var fraction = ["", ""];
                var digit = ["", "", "", "", "", "", "", "", "", ""];
                var unit = [["", "", ""], ["", "", "", ""]];

                var result = "";
                for (var i = 0; i < fraction.length; i++) {
                    var t = Math.floor(input * 10 * Math.pow(10, 1)) % 10;
                    result += (digit[Math.floor(input * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, "");
                }

                result = result || "";

                input = Math.floor(input);
                for (var i = 0; i < unit[0].length && input > 0; i++) {
                    var n = "";
                    for (var j = 0; j < unit[1].length && input > 0; j++) {
                        n = digit[input % 10] + unit[1][j] + n;
                        input = Math.floor(input / 10);
                    }

                    result = n.replace(/(零.)*零$/, "").replace(/^$/, "") + unit[0][i] + result;
                }

                result = result.replace(/(零.)*零元/, "").replace(/(零.)+/g, "").replace(/^整$/, "零元整");

                return result;
            };
        });
    </script>
</head>
<body>
    <div ng-controller="MainCtrl">
        {{ amount | toRMB }}
    </div>
</body>
</html>

  注:toRMB數字轉大寫方法存在Bug,不能完全正確轉換。

  使用$filter呼叫自定義過濾器:

app.controller("MainCtrl", ["$scope", "$filter", function ($scope, $filter) {
    $scope.amount = $filter("toRMB") (1234.53);
}]);

3.2 自定義帶引數的過濾器

  語法:

app.filter("filterName", function() {
    return function(input, param1, param2, ... ,paramN) {
        // 邏輯處理
        ...
        return result;
    };
});

  其中:param1,param2,...,paramN為過濾器使用時傳入的引數。

  示例:

<!DOCTYPE html>
<html ng-app="app">
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
        <script type="text/javascript" src="../lib/angular.min.js"></script>
        <script type="text/javascript">
            var app = angular.module("app", []);
            app.controller("ProductCtrl", ["$scope", function($scope){
                $scope.data = [
                    { ProductName: "家電", Quantity: 5000, UnitPrice: 500 },
                    { ProductName: "數碼", Quantity: 2000, UnitPrice: 200 },
                    { ProductName: "手機", Quantity: 3000, UnitPrice: 300 }
                ];
            }]);
            app.filter("greaterThan", function() {
                return function(input, unitPrice) {
                    var result = [];
                    if(typeof(unitPrice) != "undefined" && unitPrice != "") {
                        angular.forEach(input, function(item) {
                            if(item.UnitPrice > unitPrice) {
                                result.push(item);
                            }
                        });

                        return result;
                    }

                    return input;
                };
            });
        </script>
    </head>
    <body>
        <div class="container">
            <div class="row form-inline" style="padding: 5px 15px;">
                單價:<input type="text" class="form-control" ng-model="unitprice" style="width: 200px;" />
            </div>
            <table class="table table-bordered table-hover" ng-controller="ProductCtrl" style="width: 500px;">
                <thead>
                    <tr>
                        <th class="text-center">商品名稱</th>
                        <th class="text-center">數量</th>
                        <th class="text-center">單價</th>
                    </tr>
                </thead>
                <tbody>
                    <tr ng-repeat="item in data | greaterThan: unitprice">
                        <td>{{ item.ProductName }}</td>
                        <td class="text-center">{{ item.Quantity }}</td>
                        <td class="text-center">{{ item.UnitPrice | currency }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

4. 第三方過濾器外掛

4.1 angular-filter

  官網:https://github.com/a8m/angular-filter

  npm安裝:

npm install angular-filter

  示例:

<!DOCTYPE html>
<html ng-app="app">
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
    <script type="text/javascript" src="../lib/angular.min.js"></script>
    <script type="text/javascript" src="../lib/angular-filter.min.js"></script>
    <script type="text/javascript">
        var app = angular.module("app", ["angular.filter"]);
        app.controller("ProductCtrl", ["$scope", function ($scope) {
            $scope.data = [
                { ProductName: "家電", Quantity: 5000, UnitPrice: 500 },
                { ProductName: "數碼", Quantity: 2000, UnitPrice: 200 },
                { ProductName: "手機", Quantity: 3000, UnitPrice: 300 }
            ];
        }]);
    </script>
</head>
<body>
    <div class="container">
        <table class="table table-bordered table-hover" ng-controller="ProductCtrl">
            <thead>
                <tr>
                    <th class="text-center">商品名稱</th>
                    <th class="text-center">數量</th>
                    <th class="text-center">單價</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="item in data | first: 1">
                    <td>{{ item.ProductName }}</td>
                    <td class="text-center">{{ item.Quantity }}</td>
                    <td class="text-center">{{ item.UnitPrice | currency }}</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

  其中,引入外掛:

<script type="text/javascript" src="../lib/angular-filter.min.js"></script>

  在自定義模組中新增angular.filter注入:

var app = angular.module("app", ["angular.filter"]);

  angular-filter部分過濾器示例:

  集合元素

  unique:從陣列或物件中刪除重複項。

<!DOCTYPE html>
<html ng-app="app">
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" />
    <script type="text/javascript" src="../lib/angular.min.js"></script>
    <script type="text/javascript" src="../lib/angular-filter.min.js"></script>
    <script type="text/javascript">
        var app = angular.module("app", ["angular.filter"]);
        app.controller("ProductCtrl", ["$scope", function ($scope) {
            $scope.data = [
                { ProductName: "家電", Quantity: 5000, UnitPrice: 500 },
                { ProductName: "數碼", Quantity: 2000, UnitPrice: 300 },
                { ProductName: "手機", Quantity: 3000, UnitPrice: 300 }
            ];
        }]);
    </script>
</head>
<body>
    <div class="container">
        <table class="table table-bordered table-hover" ng-controller="ProductCtrl">
            <thead>
                <tr>
                    <th class="text-center">商品名稱</th>
                    <th class="text-center">數量</th>
                    <th class="text-center">單價</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="item in data | unique: 'UnitPrice'">
                    <td>{{ item.ProductName }}</td>
                    <td class="text-center">{{ item.Quantity }}</td>
                    <td class="text-center">{{ item.UnitPrice | currency }}</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

相關文章