• ngTbale真分页实现排序、搜索等功能


    一. 真分页表格基础

      1. 需求:分页,排序,搜索都是需要发API到服务端。

      2. JS实现代码:

        getStorage是localStorage一个工具方法,可以自己写这个方法。

        API参数如下:

        {

          limit: initItemCountPerPage,

          index: options1.page,

          sortKey: options1.sortKey ? encodeURIComponent(options1.sortKey) : '',

          sortType: options1.sortType ? options1.sortType: '',

          searchWord: ''

        }

    angular.module('newApp')
      .factory('ListTableSV', ['$timeout', 'ngTableParams', 'getStorage', function ($timeout, ngTableParams, getStorage) {
        var store = getStorage('localStorage');
    
        /**
         * 创建表格
         * @param options1
         * @param options2
         * @returns {ngTableParams|*}
         */
        function createListTable(options1, options2) {
          var listTable = new ngTableParams(options1, {
            counts: options2.counts,
            getData: function ($defer, params) {
              if (!listTable.isNotFisrtLoadData) {
                listTable.apiParams = initApiParams(options1);
              }
              listTable.isNotFisrtLoadData = true;
              options2.getData(listTable.apiParams).then(function (data) {
                listTable.resetCheckboxes();
                var resData = data.data.data;
                var onDataResult = options2.onDataResult;
                if (onDataResult) {
                  onDataResult(resData);
                }
                var items = resData.items;
                var dataPreprocessFunc = options2.dataPreprocessFunc;
                if (dataPreprocessFunc) {
                  dataPreprocessFunc(items);
                }
                var totalCount = resData.totalCount ? resData.totalCount : 0;
                params.items = (items && totalCount) ? items : [];
                listTable.calculatePages(totalCount);
                params.total(totalCount);
                $defer.resolve(params.items);
                return;
              }, function () {
                params.items = [];
                var totalCount = 0;
                listTable.calculatePages(totalCount);
                params.total(totalCount);
                $defer.resolve(params.items);
                return;
              });
            }
          });
          listTable.tableName = options1.tableName;
          listTable.titles = options1.titles;
          listTable.getItemId = options2.getItemId;
          listTable.toFirstPageAndReload = function () {
            if (listTable.page() == 1) {
              listTable.reload();
            } else {
              listTable.toPage(1);
            }
          };
          return listTable;
        };
    
        function initApiParams(options1) {
          var STORAGE_PAGESIZE_KEY = getKeyForStoragePageSize(options1);
          if (store.get(STORAGE_PAGESIZE_KEY)) {
            var initItemCountPerPage = store.get(STORAGE_PAGESIZE_KEY)['value'];
          } else {
            var initItemCountPerPage = options1.count;
          }
          return {
            limit: initItemCountPerPage,
            index: options1.page,
            sortKey: options1.sortKey ? encodeURIComponent(options1.sortKey) : '',
            sortType: options1.sortType ? options1.sortType: '',
            searchWord: ''
          };
        }
    
        /**
         * 初始化排序功能
         * @param listTable
         */
        function initSort(listTable, options1) {
          listTable.sortClickIndex = 0;
          listTable.sortClickDelayIndex = 0;
          listTable.sortDelay = 750;
          listTable.nextSortType = function () {
            return listTable.sortParams.type == 'asc' ? 'desc' : 'asc';
          };
          listTable.isColumnSorting = function (key) {
            return listTable.sortParams.key == key;
          };
          listTable.isColumnSortingByASC = function (key) {
            return listTable.isColumnSorting(key) && listTable.sortParams.type == 'asc';
          };
          listTable.isColumnSortingByDESC = function (key) {
            return listTable.isColumnSorting(key) && listTable.sortParams.type == 'desc';
          };
          listTable.resetSortParams = function () {
            listTable.sortParams = {
              key: options1.sortKey ? options1.sortKey : '',
              type: options1.sortType ? options1.sortType : ''
            };
          };
          listTable.toSorting = function (key, type) {
            listTable.sortClickIndex ++;
            listTable.sortParams.key = key;
            listTable.sortParams.type = type;
            $timeout(function() {
              listTable.sortClickDelayIndex ++;
              if (listTable.sortClickIndex === listTable.sortClickDelayIndex) {
                listTable.sortClickIndex = 0;
                listTable.sortClickDelayIndex = 0;
                listTable.apiParams.sortKey = encodeURIComponent(key);
                listTable.apiParams.sortType = type;
                listTable.toFirstPageAndReload();
              }
            }, listTable.sortDelay);
          }
          listTable.resetSortParams();
        };
    
        /**
         * 初始化条目选择框
         * @param listTable
         * @param withCheckboxes
         * @returns {*}
         */
        function initCheckboxes(listTable, withCheckboxes) {
          if (withCheckboxes) {
            listTable.toggleCheckAll = function () {
              var checkedCount = listTable.checkedIds().length;
              if (checkedCount == listTable.items.length) {
                listTable.deselectAll();
              } else {
                listTable.selectAll();
              }
            };
            listTable.selectAll = function () {
              listTable.resetCheckboxes();
              listTable.checkboxes.selectAll = true;
              for (var index in listTable.items) {
                listTable.checkboxes.items[listTable.getItemId(listTable.items[index])] = true;
              }
            };
            listTable.deselectAll = function () {
              listTable.resetCheckboxes();
              listTable.checkboxes.selectAll = false;
              for (var index in listTable.items) {
                listTable.checkboxes.items[listTable.getItemId(listTable.items[index])] = false;
              }
            };
            listTable.checkedIds = function () {
              var ids = [];
              for (var index in listTable.items) {
                var id = listTable.getItemId(listTable.items[index]);
                if (listTable.checkboxes.items[id]) {
                  ids.push(id);
                }
              }
              listTable.checkboxes.selectAll = listTable.items ? (listTable.items.length == ids.length) : false;
              return ids;
            }
            listTable.resetCheckboxes = function () {
              listTable.checkboxes = {
                selectAll: false,
                items: {}
              };
            };
          } else {
            listTable.resetCheckboxes = function () {
            }
          }
          listTable.resetCheckboxes();
          return listTable;
        };
    
        /**
         * 初始话分页功能
         * @param listTable 表格
         * @private
         */
        function initPagination(listTable, options1) {
          var STORAGE_PAGESIZE_KEY = getKeyForStoragePageSize(options1);
          if (store.get(STORAGE_PAGESIZE_KEY)) {
            listTable.count(store.get(STORAGE_PAGESIZE_KEY)['value']);
          }
          if (options1.page) {
            listTable.page(options1.page);
          }
          listTable.editCount = listTable.count();
    
          listTable.toCount = function (count) {
            var currentCount = listTable.count();
            if (currentCount != count) {
              listTable.count(count);
              listTable.apiParams.index = 1;
              listTable.apiParams.limit = count;
            }
          };
          listTable.prePage = function () {
            var page = listTable.page();
            if (page > 1) {
              listTable.page(page - 1);
              listTable.apiParams.index = page - 1;
            }
          };
          listTable.nextPage = function () {
            var page = listTable.page();
            if (page < Math.ceil(1.0 * listTable.total() / listTable.count())) {
              listTable.page(page + 1);
              listTable.apiParams.index = page + 1;
            }
          };
          listTable.toPage = function (page) {
            var currentPage = listTable.page();
            if (currentPage != page) {
              listTable.page(page);
              listTable.apiParams.index = page;
            }
          };
          listTable.calculatePages = function (totalCount) {
            var itemCountPerPage = listTable.count();
            store.set(STORAGE_PAGESIZE_KEY, {
              'value': itemCountPerPage
            });
            var totalPage = Math.ceil(1.0 * totalCount / itemCountPerPage);
            var currentPage = Math.max(1, Math.min(listTable.page(), totalPage));
            listTable.pages = calculateTablePages(currentPage, totalPage);
          }
        };
    
        function getKeyForStoragePageSize(options1) {
          return 'list_table_page_size@' + options1.tableName;
        };
    
        function calculateTablePages(currentPage, totalPage) {
          if (totalPage == 0) {
            return [];
          }
          var end = Math.min(9, totalPage);
          var pages = [currentPage];
          while (pages.length < end) {
            var pre = pages[0] - 1;
            var next = pages[pages.length - 1] + 1;
            if (pre >= 1) {
              pages.unshift(pre);
            }
            if (next <= totalPage) {
              pages.push(next);
            }
          }
          return pages;
        };
    
        function init(options1, options2) {
          var listTable = createListTable(options1, options2);
          initSort(listTable, options1);
          initCheckboxes(listTable, options1.withCheckboxes);
          initPagination(listTable, options1);
          return listTable;
        };
    
        return {
          init: init,
        };
      }]);

      2. html分页代码

    <div class="ng-cloak dahuo-pagination" ng-if="params.pages.length > 0">
      <div class="col-lg-6">
        <div class="dataTables_info" role="status" aria-live="polite" ng-if="params.pages.length > 0">
          {{ params.count() * (params.page() - 1) + 1 }}~
          {{ params.count() * (params.page() - 1) + params.data.length }}条,共{{
          params.total() }}条记录
        </div>
      </div>
      <div class="col-lg-6 pagination2" style="margin-bottom: 40px">
        <div class="dataTables_paginate paging_simple_numbers">
          <ul class="pagination ng-table-pagination">
            <li><a href="" ng-click="params.prePage()">上一页</a></li>
            <li ng-repeat="page in params.pages" ng-class="{'active' : page == params.page()}">
              <a href="" ng-click="params.toPage(page)">{{ page }}</a>
            </li>
            <li><a href="" ng-click="params.nextPage()">下一页</a></li>
          </ul>
        </div>
        <div class="col-lg-3 pull-right">
          <select class="select form-control" ng-model="params.editCount" ng-change="params.toCount(params.editCount)" style="padding: 6px; margin-top: 2px;min- 80px;margin-right: 10px" ng-options="size for size in params.settings().counts">
          </select>
        </div>
      </div>
    </div>

      3. 说明:

        基本实现了分页,搜索,排序(仅仅支持单个排序)等功能。搜索和排序会返回第一页。

    二. 使用方法

      服务端应该返回结果{data:{data: {items: [{name1: ...}, {...}]}}};

      1. html中Table部分的代码

        没有什么其他说的,这么写就行了。

    <div class="table-responsive">
      <table ng-table="productsTable" class="table trans-table table-hover text-left dahuo-table" template-pagination="layouts/pagination_v3.html" width="100%">
        <thead>
        <tr>
          <th width="5%" class="dahuo-table-header-th text-center" header="'ng-table/headers/checkbox.html'">
          <span class="list-checkbox">
            <input type="checkbox" ng-model="productsTable.checkboxes.selectAll" ng-disabled="productsTable.items.length < 1" ng-click="productsTable.toggleCheckAll()"/>
            <span></span>
          </span>
          </th>
          <th width="15%" ng-repeat="title in productsTable.titles" ng-class="{'sort': title.sortable}"
              ng-click="productsTable.toSorting(title.key, productsTable.nextSortType())">
            {{ title.name }}
            <li class="fa pull-right" ng-if="title.sortable" ng-class="{'fa-sort-asc': productsTable.isColumnSortingByASC(title.key), 'fa-sort-desc': productsTable.isColumnSortingByDESC(title.key), 'fa-unsorted': !productsTable.isColumnSorting(title.key)}" aria-hidden="true" ng-style="{'color' : (!productsTable.isColumnSorting(title.key) ? '#c9c9c9' : '')}"></li>
          </th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="item in $data">
          <td width="5%" header="'ng-table/headers/checkbox.html'"
              class="str-checkbox, dahuo-table-body-th text-center">
          <span class="list-checkbox">
            <input type="checkbox"  ng-model="productsTable.checkboxes.items[item.id]" disabled/>
            <span></span>
          </span>
          </td>
          <td>{{item.name1}}</td>
          <td>{{item.name2}}</a></td>
          <td>{{item.name3}}</td>
          <td>{{item.name4}}</td>
          <td>{{item.name5}}</td>
        </tr>
        <tr style="height: 100px" ng-if="$data.length < 1">
          <td colspan="6" class="text-center">暂时没有数据</td>
        </tr>
        </tbody>
      </table>
    </div>

      2. Controller调用

        DS是发送API的一个服务。这里可以改成自己要发的API,改的时候注意使用$q服务返回值。

    $scope.productsTable = new ListTableSV.init(
      {
        tableName:'fund.update.list.products',
        titles:[
          {key: 'name1', name: "名字1", sortable: true},
          {key: 'name2', name: "名字2", sortable: true},
          {key: 'name3', name: "名字3", sortable: true},
          {key: 'name4', name: "名字4", sortable: true},
          {key: 'name5', name: "名字5", sortable: true},
        ],
        withCheckboxes: true,
        page: 1,
        count: 25,
        sortKey: 'name1',
        sortType: 'desc'
      },
      {
        counts: [10, 25, 50, 100],
        getData: function(apiParams) {
          return DS.simplelist(apiParams);
        },
        getItemId: function(item) {
          return item.id;
        }
      }
    );

      

    三. 搜索的调用方法

      很好调用,就两行代码,先更改API,在reload。

    $scope.productsTable.apiParams.searchWord = encodeURIComponent($scope.keyword);
    $scope.productsTable.toFirstPageAndReload();
  • 相关阅读:
    numpy 广播
    jupyter notebook
    OpenCV ——双线性插值(Bilinear interpolation)
    历届试题 大臣的旅费
    历届试题 幸运数
    数字图像处理_读写和显示图像
    历届试题 买不到的数目
    历届试题 连号区间数
    历届试题 翻硬币
    历届试题 剪格子
  • 原文地址:https://www.cnblogs.com/ccblogs/p/5266300.html
Copyright © 2020-2023  润新知