knockoutjs是一个javascript实现的mvvm框架。非常棒。比如列表数据项增减后,不需要重新刷新整个控件片段或自己写js增删节点,只要预先定义模板和符合其语法定义的属性即可。简单的说,我们只需要关注数据的存取。
一、引言
由于最近公司的系统需要改版,改版的新系统我打算使用knockoutjs来制作web前端。在做的过程中,遇到一个问题——如何使用knockoutjs来完成分页的功能。在前一篇文章中并没有介绍使用knockoutjs来实现分页,所以在这篇文章中,将补充用knockoutjs+bootstrap来实现数据的分页显示。
二、使用knockoutjs实现分页
这里采用了两种方式来实现分页,第一种是将所有数据加载出来,然后再将所有数据分页显示;第二种是每次都只加载部分数据,每次请求都重新加载后面的数据。
对于这两种方式,使用razor方式实现的分页一般都会采用第二种方式来实现分页,但是对于单页面程序来说,第一种实现方式也有其好处,对于不是非常大量的数据完全可以采用第一种实现方式,因为这样的话,后面的数据的加载,用户体验非常的流畅。所以这里将分别介绍这两种实现方式。
2.1 每次加载部分数据的实现
这里的后端代码采用的是前一篇文章的代码,只是多加了一些示例数据而已。具体的后端实现代码为:
/// /// web api 服务,为web前端提供数据服务 /// public class taskcontroller : apicontroller { private readonly taskrepository _taskrepository = taskrepository.current; public ienumerable getall() { return _taskrepository.getall().orderby(a => a.id); } [route(api/task/getbypaged)] public pagedmodel getall([fromuri]int pageindex) { const int pagesize = 3; int totalcount; var tasks = _taskrepository.getall(pageindex, pagesize, out totalcount).orderby(a => a.id); var pagedata = new pagedmodel() { pageindex = pageindex, pageddata = tasks.tolist(), totalcount = totalcount, pagecount = (totalcount+ pagesize -1) / pagesize }; //返回数据 return pagedata; } }/// /// 任务仓储,封装了所有关于数据库的操作 /// public class taskrepository { #region static filed private static lazy _taskrepository = new lazy(() => new taskrepository()); public static taskrepository current { get { return _taskrepository.value; } } #endregion #region fields private readonly list _tasks = new list() { new task { id =1, name = 创建一个spa程序, description = spa(single page web application),spa的优势就是少量带宽,平滑体验, owner = learning hard, finishtime = datetime.parse(datetime.now.adddays(1).tostring(cultureinfo.invariantculture)) }, new task { id =2, name = 学习knockoutjs, description = knockoutjs是一个mvvm类库,支持双向绑定, owner = tommy li, finishtime = datetime.parse(datetime.now.adddays(2).tostring(cultureinfo.invariantculture)) }, new task { id =3, name = 学习angularjs, description = angularjs是mvvm框架,集mvvm和mvc与一体。, owner = 李志, finishtime = datetime.parse(datetime.now.adddays(3).tostring(cultureinfo.invariantculture)) }, new task { id =4, name = 学习asp.net mvc网站, description = glimpse是一款.net下的性能测试工具,支持asp.net 、asp.net mvc, ef等等,优势在于,不需要修改原项目任何代码,且能输出代码执行各个环节的执行时间, owner = tonny li, finishtime = datetime.parse(datetime.now.adddays(4).tostring(cultureinfo.invariantculture)) }, new task { id =5, name = 测试任务1, description = 测试任务1, owner = 李志, finishtime = datetime.parse(datetime.now.adddays(5).tostring(cultureinfo.invariantculture)) }, new task { id =6, name = 测试任务2, description = 测试任务2, owner = 李志, finishtime = datetime.parse(datetime.now.adddays(6).tostring(cultureinfo.invariantculture)) }, new task { id =7, name = 测试任务3, description = 测试任务3, owner = 李志, finishtime = datetime.parse(datetime.now.adddays(7).tostring(cultureinfo.invariantculture)) }, }; #endregion #region public methods public ienumerable getall() { return _tasks; } public ienumerable getall(int pagenumber, int pagesize, out int totalcount) { var skip = (pagenumber - 1) * pagesize; var take = pagesize; totalcount = _tasks.count; return _tasks.skip(skip).take(take); } public task get(int id) { return _tasks.find(p => p.id == id); } public task add(task item) { if (item == null) { throw new argumentnullexception(item); } item.id = _tasks.count + 1; _tasks.add(item); return item; } public void remove(int id) { _tasks.removeall(p => p.id == id); } public bool update(task item) { if (item == null) { throw new argumentnullexception(item); } var taskitem = get(item.id); if (taskitem == null) { return false; } _tasks.remove(taskitem); _tasks.add(item); return true; } #endregion }
web前端的实现代码:
@{viewbag.title = index2;layout = ~/views/shared/_layout.cshtml;}分页第二种实现方式——任务列表编号名称描述负责人创建时间完成时间状态
总共有条记录, 每页显示:条
«»
对应的js实现为:
// 实现分页的第二种方式var listviewmodel2 = function() {//viewmodel本身。用来防止直接使用this的时候作用域混乱var self = this;self.loadingstate = ko.observable(true);self.pagesize = ko.observable(3);//数据this.pagedlist = ko.observablearray();//要访问的页码this.pageindex = ko.observable(1);//总页数this.pagecount = ko.observable(1);//页码数this.allpages = ko.observablearray();//当前页this.currengepage = ko.observable(1);self.totalcount = ko.observable(1);this.refresh = function() {//限制请求页码在该数据页码范围内if (self.pageindex() self.pagecount()) {self.pageindex(self.pagecount());}//post异步加载数据sendajaxrequest(get, function (data) {// 加载新的数据前,先移除原先的数据self.pagedlist.removeall();self.allpages.removeall();self.totalcount(data.totalcount);self.pagecount(data.pagecount);self.loadingstate(false);for (var i = 1; i 0) {self.pageindex(self.pageindex() - 1);}};self.nextpage = function () {if (self.pageindex() < self.maxpageindex()) {self.pageindex(self.pageindex() + 1);}};self.allpages = ko.dependentobservable(function () {var pages = [];for (var i = 0; i <= self.maxpageindex() ; i++) {pages.push({ pagenumber: (i + 1) });}return pages;});self.movetopage = function (index) {self.pageindex(index);};};var listviewmodel = new listviewmodel();function bindviewmodel() {sendajaxrequest(get, function (data) {listviewmodel.loadingstate(false);listviewmodel.list(data);listviewmodel.totalcount(data.length);if ($('#list').length)ko.applybindings(listviewmodel, $('#list').get(0));}, null, null);}$(document).ready(function () {bindviewmodel();});
其前端页面的实现与前面的实现类似。具体页面代码如下:
@{viewbag.title = index;layout = ~/views/shared/_layout.cshtml;}任务列表编号名称描述负责人创建时间完成时间状态
总共有条记录, 每页显示:条
«»
三、运行效果
接下来,让我们看看,使用knockoutjs实现的分页效果:
四、总结
到这里,本文要介绍的内容就结束,尽管本文实现的内容相对比较简单,但是对于一些刚接触knockoutjs的朋友来说,相信本文的实现会是一个很多的指导。接下来,我将会为大家分享下angularjs的相关内容。
以上所述是小编给大家介绍的bootstrap与knockoutjs相结合实现分页效果实例详解,希望对大家有所帮助!