品优购_分页的实现

由于angular_js分页的话需要两个参数,1个是总页数,一个是本页展示的数据,  如果要查询数据库的话需要两个参数,1个事当前页数pageNum 另外一个是 一页展示的条数 numPerPage,因此我们需要封装一个对象,用来存储发送给前台的数据

------------------------第一模块:后端代码---------------------------------------------------------------------------------------

第一步:封装domain

在pyg_pojo项目中,新建一个domain 叫pageResult,另外需要实现Serializable接口实现序列化

package entity;

import java.io.Serializable;
import java.util.List;

public class PageResult implements Serializable{
    private long totalPage;
    private List rows;

    .....全参构造,无参构造
    .....getter和setter方法.
}

因为我们用****生成了pojo,mapper和mapper的实现类,所以从数据库获取数据的步骤相当于我们已经完成了,接下来我们要保证:1 在pyg_dao中导入分页的插件

第二步前的准备工作:

在pyg_dao中导入分页依赖

<!-- 分页依赖 -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
</dependency>

在pyg_dao的mybatis中导入分页插件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <plugins>
      <!-- com.github.pagehelper 为 PageHelper 类所在包名 -->
      <plugin interceptor="com.github.pagehelper.PageHelper">
         <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL 六种数据库-->
         <property name="dialect" value="mysql"/>
      </plugin>
   </plugins>
</configuration>

将pyg_servicez中的pox.xml引入pyg_dao

<dependency>
    <groupId>com.pyg</groupId>
    <artifactId>pyg_dao</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

确保以上步骤正确后,在pyg_sellersInterface中

第二步:接口pyg_sellergoods_interface

public interface BrandService {
//需求1:分页展示品牌
public PageResult findPage(int pageNum,int numPerPage);

}

第三步:接口的实现类pyg_sellergoods_service

@Service
public class BrandServiceImpl implements BrandService {
//需求1:分页功能
@Override
public PageResult findPage(int pageNum, int numPerPage) {
    PageHelper.startPage(pageNum,numPerPage);
    Page<TbBrand> page=(Page<TbBrand>) tbBrandMapper.selectByExample(null);
    return new PageResult(page.getTotal(),page.getResult());
}

第四步:控制层controller    pyg_manage_web

说明:@RestController相当于@Controller和@ResponseBody两个标签的合并用法,@Reference相当于从zookeeper中将brandService注入到pyg_manage_web项目的controller中,此处需要从前台传入两个参数,pageNum,numPerPage

@RestController
@RequestMapping("/brand")
public class BrandController {
@Reference
private BrandService brandService;
//需求1:分页展示品牌信息
@RequestMapping("findPage")
public PageResult findPage(int pageNum,int numPerPage){
       return brandService.findPage(pageNum,numPerPage);

}

------------------------------------angular框架的前端层代码如下-----------------------------------------------------------------------------------

第一步:请求的service层JS

app.service("brandService",function ($http) {
//分页查询
this.findPage=function (pageNum,numPerPage) {
    return $http.get("../brand/findPage.do?pageNum="+pageNum+"&numPerPage="+numPerPage+"");
}

}

第二步:前端baseController层JS

在baseController中一般放一些项目中所有controller都可能会用上的controoler,其他controller如果想要用baseController的内容只需要继承baseController即可. 此处我们在baseController中放置了分页需要的两个功能刷新和分页控件,另外还放置了一个选择框选中状态的方法(本分页案例暂时用不到).

app.controller("baseController",function ($scope) {

    //获取2个分页参数,网页数据传后台
    $scope.reloadlist=function () {
        $scope.search($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
    }

    //分页控件
    $scope.paginationConf= {
        //赋值就会发生变化,变化就执行下面的onchange激发一连串的变化
        currentPage: 1,   //默认目前页码
        totalItems: 0,    //默认总条数
        itemsPerPage: 10, //默认每页条数
        perPageOptions: [10, 20, 30, 40, 50], //每页展示条数选择
        //onChange只要上面默认发生变化就更新,调用reloadlist
        onChange:function () {
            $scope.reloadlist();//重新加载,查询
        }
    }

    //收集ids
    $scope.selectIds=[];

    //更新复选
    $scope.updateSelection=function ($event,id) {
        if($event.target.checked){
            $scope.selectIds.push(id);
        }else {
            var idx= $scope.selectIds.indexOf(id); //拿到此id的下标
            $scope.selectIds.splice(idx,1); //从集合中删除此id
        }
    }

});

第三步:前端controller层JS

此处注意:1 继承basecontroller和引入service     

2 在分页得到reponse后,千万记得将response.totalPage的值赋值给$scope.paginationConf.totalItems,要不然html中将没有分页标签

//这边是注入了三个参数$scope,$http,将上面请求的servie注入到controller层
app.controller("brandController",function ($scope,$controller  ,brandService) {
$controller("baseController",{$scope:$scope}) //继承,请注意继承的话需要1 在上面括号加入$controller,2 写这一句引入的话

// 根据条件查询并分页显示
//searchEntity用于接收要查询的条件
$scope.searEntity={};
$scope.search=function (pageNum,numPerPage) {
    brandService.search(pageNum,numPerPage,$scope.searEntity).success(
        function (response) {
            $scope.paginationConf.totalItems=response.totalPage;
            $scope.list=response.rows;
        }
    )
};

}

第四步:前端Html页面层

首先需要引入js在html页面中否则无法用功能,

1 引入js,这块是重点,如果以上的js文件没有引入,那么将会造成功能无法实现

<!--angular的js-->
<script src="../plugins/angularjs/angular.min.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!--分页前端js-->
<script src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!--引入service层js-->
<script src="../js/service/brandService.js" type="application/javascript"></script>
<!--引入基础功能的controller js-->
<script src="../js/controller/baseController.js" type="application/javascript"></script>
<!--引入具有分页功能的js-->
<script src="../js/controller/brandController.js" type="application/javascript"></script>

2 在body中需要引入angular相关标签用来表名是一个angular前端框架

此处需要定义ng-app="pyg" ng-controller="brandController" 两个属性

<body class="hold-transition skin-red sidebar-mini" ng-app="pyg" ng-controller="brandController" >

3 在表格table外,需要引入分页导航条

<tm-pagination conf="paginationConf"></tm-pagination>

4 在表格table中,循环展示数据

此处的list就是从前端controller中response得到的数据,因为是一个list,所以需要循环便利

{{}}括号中的内容就是从遍历的对象brand中取出的具体用来展示的数据

<tr ng-repeat="brand in list">
        <td><input  type="checkbox" ng-click="updateSelection($event,brand.id)" ></td>
        <td>{{brand.id}}</td>
        <td>{{brand.name}}</td>
        <td>{{brand.firstChar}}</td>
        <td class="text-center">                                           
        <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(brand.id)" >修改</button>
         </td>
 </tr>

激发方法:

此处分页我们在html页面无需经过激发方法,为什么呢? 

我们首先看一下basecontroller.js中我们定义了一个属性,这个js已经引入了html页面,所以当页面加载前,此js将会运行本属性(注意方法是需要激发的,而属性不需要)

$scope.paginationConf= {
currentPage: 1, //默认目前页码
currentPage: 1,   //默认目前页码
totalItems: 0,    //默认总条数
itemsPerPage: 10, //默认每页条数
perPageOptions: [10, 20, 30, 40, 50], //每页展示条数选择
//onChange只要上面默认发生变化就更新,调用reloadlist
onChange:function () {
    $scope.reloadlist();//重新加载,查询
}

接下来在basecontroller.js中此属性激发了onChange方法里面的reloadlist方法,而reladlist方法又激发了search(两个参数..)方法
此处就给方法传入了后台需要的两个参数  哪一页 和 一页展示多少条数据
$scope.reloadlist=function () {
    $scope.search($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
}

因为我们在brandcontroller页面继承了basecontroller.js,因此直接可以找到brandcontroller中的search()方法

//  根据条件查询并分页显示
//searchEntity用于接收要查询的条件
$scope.searEntity={};
$scope.search=function (pageNum,numPerPage) {
    brandService.search(pageNum,numPerPage,$scope.searEntity).success(
        function (response) {
            $scope.paginationConf.totalItems=response.totalPage;
            $scope.list=response.rows;
        }
    )
};

在brandcontroller中我们引入了brandService,所以service直接发送一个请求到后台的tomcat

//分页查询
this.findPage=function (pageNum,numPerPage) {
    return $http.get("../brand/findPage.do?pageNum="+pageNum+"&numPerPage="+numPerPage);
}

接下来大家应该能想到,后台给前台一个响应,响应是一个组合实体json,然后传送给了$scope.search=function (pageNum,numPerPage)方法,然后得到一个响应response, 然后通过双向原理向页面遍历展示数据

这就是整个分页的流程,所以激发是放在了basecontroller中激发的.

 

第五步:效果展示

成功将数据库中的数据展示在了html中,并且具有分页功能

品优购_分页的实现

 

分页功能的总结语(重点)

在分页需求中,首先我们思考,前台需要展示的内容时一个怎么样的?

后台需要前台传哪些参数,后台才可以从数据库查到前台需要的数据?

前台需要后台相应怎样的对象?

很显然后台需要两个参数去查询数据库,因为我们用的是pageHelper分页控件,pageHelper需要pageNum(哪一页)和 numPerPage(每页展示多少条),所以最终在前端的service层我们传入这两个参数

前台由于使用分页控件pagination.js,所以他需要两个参数 1个是总页数 totalPage, 一个是当页展示的数据(因为数据多,而且是list,我们需要封装),因为在后端中我们做了一个组合对象,封装了两个成员变量1 总页数totalPage,2 总数据rows(List类型的)