由于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类型的)