1. 程式人生 > >Angularjs 前端資料用orderBy排序,單表頭和多表頭處理,單表頭不預設排序

Angularjs 前端資料用orderBy排序,單表頭和多表頭處理,單表頭不預設排序

  orderBy這個功能其實是內建的過濾器,他可以在html和js程式碼中使用

    html:{{ orderBy_expression | orderBy : expression : reverse}}

    js    :$filter('orderBy')(array, expression, reverse)

    在這裡我們只看html標籤的運用,可以看出來他需要傳入三個值

      1.orderBy_expression :你需要排序的陣列

      2.expression :你需要根據哪個條件排序

      3.reverse :正序還是倒序(boolean)

下面是單個表頭:

<table class="table table-bordered table-striped table-hover">
                    <thead>
                        <tr>
                            <th class="m-th" ng-repeat="service in servicesTitle" ng-click="toggle_sort(service.name,'services')">
                                {{service.value}}
                                <i class="position-rg" ng-class="{'fa fa-sort-desc sort_bg':isSortUp(service.name,'services'),'fa fa-sort-asc sort_bg':isSortDown(service.name,'services')}"></i>
                                <i class="fa fa-sort position-rg" aria-hidden="true"></i>
                            </th>
                        </tr>
                    </thead>
                    <tbody ng-show="services.filteredList.length == 0">
                        <tr>
                            <td colspan="1">沒有查詢到任何資料</td>
                        </tr>
                    </tbody>
                    <tbody>
                        <tr ng-click="getServiceNodesList(info)" ng-class="statusStyle(info)" ng-repeat="info in services.filteredList | filter:search.serviceName | ownOrderBy:services.sort:services.reverse | pagination:services.pageNo:services.pageSize">
                            <td>{{info}}</td>
                        </tr>
                    </tbody>
</table>

下面是多個表頭:
<table class="table table-bordered table-striped table-hover">
                    <thead>
                        <tr>
                            <th>選中</th>
                            <th ng-repeat="node in nodesTitle" class="m-th" ng-click="toggle_sort(node.name,'nodes')">
                                {{node.value}}
                                <i class="position-rg" ng-class="{'fa fa-sort-desc sort_bg':isSortUp(node.name,'nodes'),'fa fa-sort-asc sort_bg':isSortDown(node.name,'nodes')}"></i>
                                <i class="fa fa-sort position-rg" aria-hidden="true"></i>
                            </th>
                        </tr>
                    </thead>
                    <tbody ng-show="nodes.filteredList.length == 0">
                        <tr>
                            <td colspan="4">沒有查詢到任何資料</td>
                        </tr>
                    </tbody>
                    <tbody>
                        <tr ng-repeat="info in nodes.filteredList | filter:search.nodeName | orderBy:nodes.sort:nodes.reverse | pagination:nodes.pageNo:nodes.pageSize">
                            <td><input type="checkbox" id="nodeNameCheck{{info.nodeName}}" ng-click="selectNode(info);"
                                        ng-model="info.checked"></input>
                            </td>
                            <td>{{info.nodeName}}</td>
                            <td>{{info.nodeIp}}</td>
                            <td>{{info.fluidSpeedSize}}</td>
                        </tr>
                    </tbody>
                </table>

js中表頭定義:
$scope.servicesTitle = [{
            "name": 'service',
            "value": '服務列表'
        }
        ];
        $scope.nodesTitle = [{
            "name": 'nodeName',
            "value": '節點名稱'
        }, {
            "name": 'nodeIp',
            "value": '節點IP'
        }, {
            "name": 'fluidSpeedSize',
            "value": '流控引數值'
        }
        ];

js中排序變數定義:
 $scope.services = {
            sort: undefined, //用來排序的欄位
            reverse: false, //用於排序升序降序
            filteredList: []//條件過濾後的結果
        };
 $scope.nodes = {
            sort: undefined, //用來排序的欄位 
            reverse: false, //用於排序升序降序
            filteredList: []//條件過濾後的結果
        };


js中ng-click排序方法,和排序圖示顯示

       $scope.toggle_sort = function (filedName, name) {
            if ($scope[name].sort === filedName) {
                $scope[name].reverse = !$scope[name].reverse;
            } else {
                $scope[name].sort = filedName;
                $scope[name].reverse = false;
            }
        }

        //用於顯示指示器
        $scope.isSortUp = function (filedName, name) {
            return $scope[name].sort === filedName && !$scope[name].reverse;
        }

        $scope.isSortDown = function (filedName, name) {
            return $scope[name].sort === filedName && $scope[name].reverse;
        }


自己寫的ownOrderBy過濾器
'use strict';
angular.module("adminApp")
     .filter('ownOrderBy',['$filter',function($filter){
         return function(inputArray,sort,reverse){
            if(sort === undefined){
               return inputArray;
            } else {
                if(reverse === false){
                    var temp = $filter('orderBy')(inputArray, undefined, reverse);
                }else{
                   var temp = $filter('orderBy')(inputArray, sort, reverse);
                }
               return temp;
            }   
        }
     }]);


解釋:

        之所以要在單表頭的時候,自己寫一個過濾器,是因為angularjs內建的orderBy在單表頭的時候預設給我升序排序了,而他的排序又只是在檢視層面更新,不會更新我的scope域中的資料,可是我需要獲取第一行的值,使那一行高亮,並傳給另一個服務,獲取相關聯的其他資料。

        嘗試了半天,把排序欄位初始值設定為undefined和null,他都會給我排序,所以乾脆自己寫一個過濾器。

        判斷一下,初始的時候,如果排序欄位是undefined,則返回原陣列即可,否則,用angular自帶的orderBy。後面因為reverse===false升序的時候,它又沒有升序,把排序欄位變為undefined的時候,他就預設升序了。所以才又針對reverse做了一次判斷。

        個人覺得可能是單表頭的原因,因為多個表頭的時候,就沒有這種問題,多個表頭的時候,初始排序欄位為undefined,他就不知道要按哪個排序,就沒有排序。

        如果有人知道原因,歡迎不吝賜教,萬分感激。