博客
关于我
利用Bootstrap Paginator插件和KnockoutJS完成分页功能
阅读量:396 次
发布时间:2019-03-05

本文共 8738 字,大约阅读时间需要 29 分钟。

  在最近一个项目中,需要结合一堆条件查询并对查询的结果数据完成一个简单分页功能,可是做着做着,自己的思路越来越模糊,做到心态崩溃!!! 哈哈,特此花点时间重新总结,并从最简单的分页,然后向多条件查询分页慢慢过渡,或许有人觉得这个很简单(可以绕道啦,哈哈),却是对基础知识的一次学习过程。

  Demo地址:

  本文地址:

 

一、环境介绍

  分页功能很多已有的很完美的插件或是第三方应用包都能够完美实现,我在此利用了一些前端插件来完成分页功能。

  前端的插件完成前端分页数字之类的切换展示;

  利用插件完成分页数据的绑定;

  在后端,利用asp.net core mvc 完成分页信息的接收和处理工作。

 

二、简单分页

  完成对已有数据的分页功能,不带条件查询。

  首先,一上来便是完成数据绑定工作:

1   bookList: ko.mapping.fromJS(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model))),//展示数据2   pageEntity: ko.mapping.fromJS(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(new PageRequestViewModel()))),//分页信息

    页面刚展示的时候得有分页数据吧,可以在当页面展示的时候,数据也带过来了,也可以页面展示后,再通过ajax去后台调用,我选择后者。

  在页面启动时,调用该函数完成初始化页面数据。

1     getBookData: function () { 2         var pageEntity = ko.mapping.toJS(viewModel.pageEntity); 3         $.ajax({ 4             url: '@Url.Action("SampleGetData")', 5             type: 'POST', 6             dataType: 'json', 7             data: pageEntity, 8             success: function (result) { 9                 ko.mapping.fromJS(result.data, viewModel.bookList);10                 options.totalPages = result.totalCount > 0 ? result.totalCount % options.numberOfPages == 0 ?11                     result.totalCount / options.numberOfPages : (result.totalCount / options.numberOfPages) + 1 : 1;12                 $('#pagination').bootstrapPaginator(options);13             }14         });15     }

   分页信息(当前页面,页面展示数据条数)带过去,后台根据分页信息完成数据查询,并获得总的记录条数用于前端页面计算总页数。

1     [HttpPost] 2     public IActionResult SampleGetData(PageRequestViewModel pageEntity) 3     { 4         var bookList = PageDataSeed.GetPageDataList() 5             .Skip((pageEntity.PageIndex - 1) * pageEntity.PageSize) 6             .Take(pageEntity.PageSize); 7  8         var pageResultViewModel = new PageResultViewModel
() 9 {10 PageIndex = pageEntity.PageIndex,11 PageSize = pageEntity.PageSize,12 TotalCount = PageDataSeed.GetPageDataList().Count(),13 Data = bookList14 };15 16 return Json(pageResultViewModel);17 }

 根据分页信息查询也就搞定了,当点击底部的页面码的时候得改变当前分页信息,然后要切换当前分页信息所对应的数据出来,在Bootstrap paginator插件中,点击页面码有一个函数onPageClicked,点击具体的某一页后,根据参数page获得页面,改变当前展示的页面码数字,并对分页信息修改,然后再次调用ajax获得新数据。

1     onPageClicked: function (event, originalEvent, type, page) {2         options.currentPage = page;3         viewModel.pageEntity.PageIndex = page;4         viewModel.getBookData();5     },

  至此,简单分页功能便搞定了,在此实现中,偏重于前端实现分页逻辑,后台只是取得相应的数据。

  

三、单条件查询分页

  复制一份简单分页后,改造下加入一个根据书名条件项,查询后完成分页功能。

  首先加入书名绑定,在此用了两个书名,第二个是有目的性的留着,也只是我的理解,条件查询后,如果底部展示有多页,那么我在点击每一页的时候,我的查询条件不能动吧,基于此考虑的。

1     bookName: ko.observable(),2     bookNameBackup: ko.observable(),

  数据查询部分改动不大,主要是把查询条件加入进来,因此只改动data参数即可。

1     getBookData: function () { 2         var pageEntity = ko.mapping.toJS(viewModel.pageEntity); 3         $.ajax({ 4             url: '@Url.Action("SingleQueryGetData")', 5             type: 'POST', 6             dataType: 'json', 7             data: {"pageEntity":pageEntity, "bookName":viewModel.bookName()}, 8             success: function (result) { 9                 ko.mapping.fromJS(result.data, viewModel.bookList);10                 options.totalPages = result.totalCount > 0 ? result.totalCount % options.numberOfPages == 0 ?11                     result.totalCount / options.numberOfPages : (result.totalCount / options.numberOfPages) + 1 : 1;12                 $('#pagination').bootstrapPaginator(options);13             }14         });15     },

  前端Html部分加入单条件项,以书名为例,查询按钮绑定点击后的触发函数

1     
2
3
4
5
6
7

  点击查询后执行函数,将当前页面重置为1,查询数据,并记录该次查询的查询条件。

1   //查询2     queryBookList: function () {3         options.currentPage = 1;4         viewModel.pageEntity.PageIndex = options.currentPage;5         viewModel.getBookData();6         viewModel.bookNameBackup(viewModel.bookName());//记录查询条件,分页点击时需要用到7     }

  查询完毕,然后假设底部还存在很多页面码可以选择,当我们点击页面码的时候,因为查询条件仍然存在,我们点击后仍然会完成分页功能,但是!!!

  当把查询条件清空,比如在此demo中,把书名置空,此时不点查询按钮,而是直接点击页面码,那情况会如何呢,查询条件已经没了;

  或是说查询条件为空时,输入查询条件,不点查询按钮,直接点击页面码;

  这都是不合理的情形,点击页面码的时候肯定得保证原查询条件的存在,至少我是这么想的,或许您有更好的建议,请告诉我,十分感谢。这也就是我在之前设置了一个监控对象bookNameBackup的原因,备份查询条件,防止点击页码切换时查询条件变更的情形。

  前端已经改好了,然后进入后端来改一下,先对条件判空处理,然后执行相应的逻辑。

1     [HttpPost] 2     public IActionResult SingleQueryGetData(PageRequestViewModel pageEntity, string bookName) 3     { 4         IEnumerable
bookList = PageDataSeed.GetPageDataList(); 5 PageResultViewModel
pageResultViewModel = null; 6 7 if (!string.IsNullOrEmpty(bookName)) 8 bookList = bookList.Where(b => b.BookName.Contains(bookName)); 9 10 var books = bookList.Skip((pageEntity.PageIndex - 1) * pageEntity.PageSize)11 .Take(pageEntity.PageSize);12 13 pageResultViewModel = new PageResultViewModel
()14 {15 PageIndex = pageEntity.PageIndex,16 PageSize = pageEntity.PageSize,17 TotalCount = bookList.Count(),18 Data = books19 };20 21 return Json(pageResultViewModel);22 }

  单条件查询分页功能也就搞定了,查询和点击页面码所执行的逻辑是不一样的,虽然都调用到了最终的数据查询方法,但是对于条件的处理是不一样的。

   

四、多条件查询分页

  对单条件查询分页下多加入几个条件,进入到多条件查询,变化其实不大,只是为了方便管理如此多的查询条件,改成了以对象形式管理

  首先绑定查询对象信息,该对象中包括了三个查询条件,书名,作者,出版社,仍然设置一个备份对象,原因和单条件查询下是一样的。

1     queryItemEntity: ko.mapping.fromJS(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(new QueryItemViewModel()))),//查询条件信息2     queryItemEntityBackup: ko.mapping.fromJS(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(new QueryItemViewModel()))),//查询条件信息备份

  页面的查询条件多了,通过queryItemEntity为前缀展示,也方便维护

1     
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

  查询条件改动,也使得数据查询部分的条件改变了,将查询条件整体封装,而不是零散的传递,改动之处加入了第三行将ko上的查询条件信息转换为JS对象和改变了参数data的值。

1   getBookData: function () { 2         var pageEntity = ko.mapping.toJS(viewModel.pageEntity); 3         var queryItemEntity = ko.mapping.toJS(viewModel.queryItemEntity); 4  5         $.ajax({ 6             url: '@Url.Action("MultipleQueryGetData")', 7             type: 'POST', 8             dataType: 'json', 9             data: { "pageEntity": pageEntity, "queryItemEntity": queryItemEntity},10             success: function (result) {11                 ko.mapping.fromJS(result.data, viewModel.bookList);12                 options.totalPages = result.totalCount > 0 ? result.totalCount % options.numberOfPages == 0 ?13                     result.totalCount / options.numberOfPages : (result.totalCount / options.numberOfPages) + 1 : 1;14                 $('#pagination').bootstrapPaginator(options);15             }16         });17     },

   点击按钮查询处的逻辑还是没有改变,仍然是查询记录并将查询条件备份,用于分页控件中页面码的点击函数。

1     //查询2     queryBookList: function () {3         options.currentPage = 1;4         viewModel.pageEntity.PageIndex = options.currentPage;5         viewModel.getBookData();6         ko.mapping.fromJS(viewModel.queryItemEntity, viewModel.queryItemEntityBackup);//记录查询条件,分页点击时需要用到7     }

   对于前端来讲改动并不是很大,无非是将查询条件封装一下,同样后端的改动只是多个查询条件的过滤,依次比对三个查询条件是否为空,并挨个去完成查询的过滤。

1     [HttpPost] 2     public IActionResult MultipleQueryGetData(PageRequestViewModel pageEntity, QueryItemViewModel queryItemEntity) 3     { 4         var bookList = PageDataSeed.GetPageDataList(); 5  6         #region 条件过滤 7         if (!string.IsNullOrEmpty(queryItemEntity.BookName)) 8             bookList = bookList.Where(b => b.BookName.Contains(queryItemEntity.BookName)).ToList(); 9         if (!string.IsNullOrEmpty(queryItemEntity.Author))10             bookList = bookList.Where(b => b.Author.Contains(queryItemEntity.Author)).ToList();11         if (!string.IsNullOrEmpty(queryItemEntity.Press))12             bookList = bookList.Where(b => b.Press.Contains(queryItemEntity.Press)).ToList();13         #endregion14 15         var books = bookList.Skip((pageEntity.PageIndex - 1) * pageEntity.PageSize).Take(pageEntity.PageSize);16 17         var pageResultViewModel = new PageResultViewModel
()18 {19 PageIndex = pageEntity.PageIndex,20 PageSize = pageEntity.PageSize,21 TotalCount = bookList.Count(),22 Data = books23 };24 25 return Json(pageResultViewModel);26 }

  多条件查询分页的效果展示

  

  至此,查询功能算是简单完成了,或许还有漏洞地方,没有发现,特别是逻辑漏洞,防不胜防,望多指教,感谢。

  设计一个小Demo一方面是对分页功能进行一下总结,以防自己若干天或是若干年后还需要,可以回来看看,一方面也是如果有需要的朋友可以加快编码和设计的过程。

  码云上存放Demo的地址:

 

2018-6-24,望技术有成后能回来看见自己的脚步

  

转载地址:http://joozz.baihongyu.com/

你可能感兴趣的文章
Angular2笔记:NgModule
查看>>
Liunx百宝箱(Centos补充)
查看>>
Python存储系统(Redis)
查看>>
C语言指针收藏
查看>>
.net 4种单例模式
查看>>
T4 生成数据库实体类
查看>>
C#搞个跨平台的桌面NES游戏模拟器
查看>>
手把手教你安装Eclipse最新版本的详细教程 (非常详细,非常实用)
查看>>
《带你装B,带你飞》pytest成魔之路4 - fixture 之大解剖
查看>>
互联网App应用程序测试流程及测试总结
查看>>
根据轨迹分析出用户家在哪
查看>>
PostgreSQL查询表名称及表结构
查看>>
为什么现在使用多周期CPU,而单周期CPU被弃用?
查看>>
<Git命令使用>当前版本,历史版本,版本切换
查看>>
是什么?评估分类器的常用概念----准确率,精确率,召回率
查看>>
linux中使用awk命令
查看>>
LAB2 内核的内存管理
查看>>
如何使用google搜索?
查看>>
浅析接口和抽象类的区别与使用场景
查看>>
HashSet和HashMap的区别
查看>>