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 ‘[email protected]‘ + 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-width: 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();
时间: 2024-10-14 04:10:44

ngTbale真分页实现排序、搜索等功能的相关文章

YII2原生SQL分页支持排序搜索

YII2默认情况下会生成一个直接操作单表的模型并且具备搜索和分页以及排序功能,在很多复杂的业务逻辑需求中,单表操作很难实现我们想要的效果,此时我要是选择的话就用纯sql来做,不用考虑那么多的对应关系,而且你得SQL语句执行效率越高,程序执行的效率也就越高. OK我们来看看怎么实现. 一.首先我们来看一个需求:在一个博客的首页中,需要显示博客列表,列表中(作者,文章标题,发表时间,文章分类,评论数量)需要显示. 二.建表 yii_article(文章):[id,title,publish_time

Django中使用JS通过DataTable实现表格前端分页,每页显示页数,搜索等功能

版本: django:2.1.7 python:3.7 Django架构中自带了后端分页的技术,通过Paginator进行分页,前端点击按钮提交后台进行页面切换. 优缺点:后端分页对于数据量大的场景有其优势,但页面切换比较慢. 后端分页python3代码如下: paginator = Paginator(stat_list, numtmp) try: flight_stats = paginator.page(1) except PageNotAnInteger: flight_stats =

SpringBoot JPA实现增删改查、分页、排序、事务操作等功能

今天给大家介绍一下SpringBoot中JPA的一些常用操作,例如:增删改查.分页.排序.事务操作等功能.下面先来介绍一下JPA中一些常用的查询操作: //And --- 等价于 SQL 中的 and 关键字,比如 findByHeightAndSex(int height,char sex): public List<User> findByHeightAndSex(int height,char sex); // Or --- 等价于 SQL 中的 or 关键字,比如 findByHeig

02 - Unit08:搜索笔记功能、搜索分页、处理插入数据库乱码问题

搜索笔记功能 按键监听事件 $("#search_note").keydown(function(event){ var code=event.keyCode; if(code==13){ 请求发送 } }) select * from cnshare cnshare_title like '%' 发送Ajax请求 事件绑定:键盘监听事件(keydown) 获取参数:keyword,作为模糊查询的基础 发送请求:/share/find.do 服务器处理 ShareController.

easyui datagrid 客户端搜索、分页、排序

easyui datagrid的排序默认是服务器端排序,可以用sorter实现客户端排序[2]:客户端分页可用filter实现[3]:客户端搜索同样可以用filter实现. 不多说直接上代码: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="keywords" con

Android中ListView字母排序,实现字母挤压效果以及右侧快速选中字母,搜索关键字功能

Android中ListView字母排序,实现字母挤压效果以及右侧快速选中字母,搜索关键字功能 本文中阐述如何自定义EditText实现搜索框自定义的样式以及挤压字母的思路等 自定义EditText 相关的drawable文件 主界面以及相关的适配器 结果展示 定义要呈现的EditText的样式 public class ClearEditText extends EditText implements OnFocusChangeListener, TextWatcher { /** * 定义删

使用插件bootstrap-table实现表格记录的查询、分页、排序等处理

在业务系统开发中,对表格记录的查询.分页.排序等处理是非常常见的,在Web开发中,可以采用很多功能强大的插件来满足要求,且能极大的提高开发效率,本随笔介绍这个bootstrap-table是一款非常有名的开源表格插件,在很多项目中广泛的应用.Bootstrap-table插件提供了非常丰富的属性设置,可以实现查询.分页.排序.复选框.设置显示列.Card view视图.主从表显示.合并列.国际化处理等处理功能,而且该插件同时也提供了一些不错的扩展功能,如移动行.移动列位置等一些特殊的功能,插件可

动态多条件查询分页以及排序(一)--MVC与Entity Framework版url分页版

一.前言 多条件查询分页以及排序  每个系统里都会有这个的代码 做好这块 可以大大提高开发效率  所以博主分享下自己的6个版本的 多条件查询分页以及排序 二.目前状况 不论是ado.net 还是EF 在做多条件搜索时 都有这类似的代码 这样有几个不好的地方 1.当增加查询条件,需要改代码,对应去写相应的代码. 2.对多表查询以及or的支持 不是很好.而我们很常见的需求不可能是一个表的查询 3. 这样写表示层直接出现 了SQL语句 或者 linq 的拉姆达表达式  这是很不好的 表示层不应该知道数

剖析Elasticsearch集群系列之三:近实时搜索、深层分页问题和搜索相关性权衡之道

转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part03 近实时搜索 虽然Elasticsearch中的变更不能立即可见,它还是提供了一个近实时的搜索引擎.如前一篇中所述,提交Lucene的变更到磁盘是一个代价昂贵的操作.为了避免在文档对查询依然有效的时候,提交变更到磁盘,Elasticsearch在内存缓冲和磁盘之间提供了一个文件系统缓存.内存缓存(默认情况下)每1秒刷新一次,在文件系统缓存中使