手写前端分页组件

手写前端分页组件

服务端接口开发

Mybatis-PageHelper

  • 个人理解

    Mybatis-PageHelper的原理是通过AOP在截获我们执行的SQL的时候,再执行一次SQL语句,填充到返回值里

  • 使用方法

    在pom.xml中添加相关依赖

    <!-- mybatis pager -->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>4.1.0</version>
    </dependency>
    
    <dependency>
      <groupId>com.github.miemiedev</groupId>
      <artifactId>mybatis-paginator</artifactId>
      <version>1.2.17</version>
    </dependency>
    
    <dependency>
      <groupId>com.github.jsqlparser</groupId>
      <artifactId>jsqlparser</artifactId>
      <version>0.9.4</version>
    </dependency>
    

在applicationContext-datasource.xml文件中添加相关配置,设置方言为mysql

<!-- 分页插件 -->
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageHelper">
                    <property name="properties">
                        <value>
                            dialect=mysql
                        </value>
                    </property>
                </bean>
            </array>
        </property>

在ProductController.java的list接口添加如下配置,对于不是必传的搜索字段,要置成false,因为在RqquestParam.class注解中规定了default true,即使自己在搜索的时候,不传关键字,require也一定要置为false。动态分页需要用到两个参数pageNumpageSize

 @RequestMapping("list.do")
    @ResponseBody
    public ServerResponse<PageInfo> list(@RequestParam(value = "keyword",required = false)String keyword,
                                         @RequestParam(value = "categoryId",required = false)Integer categoryId,
                                         @RequestParam(value = "pageNum",defaultValue = "1") int pageNum,
                                         @RequestParam(value = "pageSize",defaultValue = "10")int pageSize,
                                         @RequestParam(value = "orderBy",defaultValue = "")String orderBy){
        return iProductService.getProductByKeywordCategory(keyword, categoryId, pageNum, pageSize, orderBy);
    }

在ProductServiceImpl.java接口实现中,添加如下配置

public ServerResponse<PageInfo> getProductByKeywordCategory(String keyword,Integer categoryId,int pageNum,int pageSize,String orderBy){
        if(StringUtils.isBlank(keyword) && categoryId == null){
            return  ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }
        List<Integer> categoryIdList = new ArrayList<Integer>();
        if(categoryId != null){
            Category category = categoryMapper.selectByPrimaryKey(categoryId);
            if(category == null && StringUtils.isBlank(keyword)){
                // 没有该分类,并且还没有关键字,这个时候返回一个空的结果集,不报错
                PageHelper.startPage(pageNum, pageSize);
                List<ProductListVo> productListVoList = Lists.newArrayList();
                PageInfo pageInfo = new PageInfo(productListVoList);
                return ServerResponse.createBySuccess(pageInfo);
            }
            categoryIdList = iCategoryService.selectCategoryAndChildrenById(category.getId()).getData();
        }
        if(StringUtils.isNotBlank(keyword)){
            keyword = new StringBuilder().append("%").append(keyword).append("%").toString();
        }
        PageHelper.startPage(pageNum, pageSize);
        // 排序处理
        if(StringUtils.isNotBlank(orderBy)){
            if(Const.ProductListOrderBy.PRICE_ASC_DESC.contains(orderBy)){
                //PageHelper.orderBy方法的参数是(peice desc)中间含有空格,需要分割再拼接
                String[] orderByArray = orderBy.split("_");
                PageHelper.orderBy(orderByArray[0]+" "+orderByArray[1]);
            }
        }
        List<Product> productList = productMapper.selectByNameAndCategoryIds(StringUtils.isBlank(keyword)?null:keyword,categoryIdList.size()==0?null:categoryIdList);
        List<ProductListVo> productListVoList = Lists.newArrayList();
        for(Product product : productList){
            ProductListVo productListVo = assembleProductListVo(product);
            productListVoList.add(productListVo);
        }
        PageInfo pageInfo = new PageInfo(productList);
        pageInfo.setList(productListVoList);
        return ServerResponse.createBySuccess(pageInfo);
    }

前端分页组件开发

html预留分页容器

<!--分页容器-->
      <div class="pagination">
</div>

在list/index.js列表中,加载分页

'use strict';
require('./index.css');
require('page/common/nav/index.js');
require('page/common/header/index.js');
var _mm           = require('util/mm.js');
var _product      = require('service/product-service.js');
var Pagination      = require('util/pagination/index.js');
var templateIndex = require('./index.string');

var page = {
  data : {
    listParam : {
      keyword     : _mm.getUrlParam('keyword')    || '',
      categoryId  : _mm.getUrlParam('categoryId') || '',
      orderBy     : _mm.getUrlParam('orderBy')    || 'default',
      pageNum     : _mm.getUrlParam('pageNum')    || 1,
      pageSize    : _mm.getUrlParam('pageSize')   || 10
    }
  },
  init : function(){
    this.onLoad();
    this.bindEvent()
  },
  onLoad :function(){
    this.loadList();
  },
  bindEvent : function(){
    var _this = this;
    // 排序的点击事件
    $('.sort-item').click(function(){
      var $this = $(this);
      // 页码置为1
      _this.data.listParam.pageNum= 1;
      // 如果点击的是默认排序
      if($this.data('type') === 'default'){
        // 已经是active样式
        if($this.hasClass('active')){
          return;
        }
        // 其他
        else{
          $this.addClass('active').siblings('.sort-item')
            .removeClass('active asc desc');
            _this.data.listParam.orderBy = 'default';
        }
      }
      //点击价格排序
      else if($this.data('type') === 'price'){
        // active类的处理
        $this.addClass('active').siblings('.sort-item')
        .removeClass('active asc desc');
        // 升序的处理
        if(!$this.hasClass('asc')){
          $this.addClass('asc').removeClass('desc');
          _this.data.listParam.orderBy = 'price_asc';
        }
        // 降序的处理
        else{
          $this.addClass('desc').removeClass('asc');
          _this.data.listParam.orderBy = 'price_desc';
        }
      }
      // 重新加载列表
      _this.loadList();
    });
  },

  // 加载list数据
  loadList : function(){
    var _this   = this,
      listHtml  = '',
      listParam = this.data.listParam,
      $pListCon = $('.p-list-con');
      //每次加载之前,显示loading
      $pListCon.html('<div class="loading"></div>');
      // 删除参数中不必要的字段
    listParam.categoryId
    ? (delete listParam.keyword) : (delete listParam.categoryId);
    // 请求接口
    _product.getProductList(listParam, function(res){
      listHtml = _mm.renderHtml(templateIndex, {
        list : res.list
      });

      $pListCon.html(listHtml);
      _this.loadPagination({
        hasPreviousPage : res.hasPreviousPage,
        prePage         : res.prePage,
        hasNextPage     : res.hasNextPage,
        nextPage        : res.nextPage,
        pageNum         : res.pageNum,
        pages           : res.pages,
      });
    }, function(errMsg){
      _mm.errorTips(errMsg);
    });
  },

  //加载分页信息
  loadPagination : function(pageInfo){
    var _this = this;
    this.pagination ? '' : (this.pagination = new Pagination());
    this.pagination.render($.extend({}, pageInfo, {
      container : $('.pagination'),
      onSelectPage : function(pageNum){
        _this.data.listParam.pageNum = pageNum;
        _this.loadList();
      }
    }));
  }

};
$(function(){
  page.init();
})

封装分页组件

pagination
  ├─index.css
  ├─index.js
  ├─index.string
  • index.js
'use strict';
require('./index.css');
var _mm = require('util/mm.js');
var templatePagination = require('./index.string');

var Pagination = function(){
  var _this = this;
  this.defaultOption = {
    container    : null,
    pageNum      : 1,
    pageRange    : 3,
    onSelectPage :null
  };
  // 事件的处理
  $(document).on('click', '.pg-item', function(){
    var $this = $(this);
    // 对于active和disabled按钮点击,不做处理
    if($this.hasClass('active') || $this.hasClass('disabled')){
        return;
    }
    typeof _this.option.onSelectPage === 'function'
        ? _this.option.onSelectPage($this.data('value')) : null;
});

};

// 渲染分页组件
Pagination.prototype.render = function(userOption){
  // 合并选项
  this.option = $.extend({},this.defaultOption,userOption);
  // 判断容器是否为合法的jQuery对象
  if(!(this.option.container instanceof jQuery)){
    return;
  }
  // 判断分页是否只有一页
  if(this.option.pages <= 1){
    return;
  }
  // 渲染分页内容
  this.option.container.html(this.getPaginationHtml());
};

// 获取分页的html, |上一页| 1 2 3 4 =5= 6 |下一页| 5/6
Pagination.prototype.getPaginationHtml = function(){
  var html      = '',
      option    = this.option,
      pageArray = [],
      start     = option.pageNum - option.pageRange > 0
        ? option.pageNum - option.pageRange : 1,
      end       = option.pageNum + option.pageRange < option.pages
        ? option.pageNum + option.pageRange : option.pages;
  // 上一页按钮的数据
  pageArray.push({
    name     : '上一页',
    value    : this.option.prePage,
    disabled : !this.option.hasPreviousPage
  });
  // 数字按钮的处理
  for(var i = start; i<= end; i++){
    pageArray.push({
      name     : i,
      value    : i,
      active : (i === option.pageNum)
    })
  };

  // 下一页按钮的数据
  pageArray.push({
    name     : '下一页',
    value    : this.option.nextPage,
    disabled : !this.option.hasNextPage
  });
  html = _mm.renderHtml(templatePagination, {
    pageArray : pageArray,
    pageNum   : option.pageNum,
    pages     : option.pages
  });
  return html;

};

module.exports = Pagination;
  • index.css

    .pg-content{
      text-align: center;
      color: #333;
    }
    .pg-content .pg-item{
      display: inline-block;
      height: 36px;
      line-height: 36px;
      padding: 0 15px;
      margin: 0 2px;
      border: 1px solid #ccc;
      background: #eee;
      cursor: pointer;
      -moz-user-select: none;
      -webkit-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
    .pg-content .pg-item.disabled{
      color: #ccc;
      background: none;
      cursor: auto;
    }
    .pg-content .pg-item.active{
      border: 1px solid #f6f6f6;
      background: none;
      cursor: auto;
    }
    .pg-content.pg-total{
      margin-left: 10px;
      background: none;
      cursor: auto;
    }
    
  • index.string

    <div class="pg-content">
      {{#pageArray}}
      {{#disabled}}
        <span class="pg-item disabled" data-value="{{value}}">{{name}}</span>
      {{/disabled}}
    
      {{^disabled}}
        {{#active}}
          <span class="pg-item active" data-value="{{value}}">{{name}}</span>
        {{/active}}
    
        {{^active}}
          <span class="pg-item" data-value="{{value}}">{{name}}</span>
        {{/active}}
    
      {{/disabled}}
      {{/pageArray}}
      <span class="pg-total">{{pageNum}} / {{pages}}</span>
    </div>
    

猜你喜欢

转载自www.cnblogs.com/hsbolg/p/12751102.html