麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

Bootstrap與KnockoutJs相結合實現分頁效果實例詳解

2019-11-20 10:10:34
字體:
來源:轉載
供稿:網友

KnockoutJS是一個JavaScript實現的MVVM框架。非常棒。比如列表數據項增減后,不需要重新刷新整個控件片段或自己寫JS增刪節點,只要預先定義模板和符合其語法定義的屬性即可。簡單的說,我們只需要關注數據的存取。

一、引言

  由于最近公司的系統需要改版,改版的新系統我打算使用KnockoutJs來制作Web前端。在做的過程中,遇到一個問題――如何使用KnockoutJs來完成分頁的功能。在前一篇文章中并沒有介紹使用KnockoutJs來實現分頁,所以在這篇文章中,將補充用KnockoutJs+Bootstrap來實現數據的分頁顯示。

二、使用KnockoutJs實現分頁

  這里采用了兩種方式來實現分頁,第一種是將所有數據加載出來,然后再將所有數據分頁顯示;第二種是每次都只加載部分數據,每次請求都重新加載后面的數據。

  對于這兩種方式,使用Razor方式實現的分頁一般都會采用第二種方式來實現分頁,但是對于單頁面程序來說,第一種實現方式也有其好處,對于不是非常大量的數據完全可以采用第一種實現方式,因為這樣的話,后面的數據的加載,用戶體驗非常的流暢。所以這里將分別介紹這兩種實現方式。

2.1 每次加載部分數據的實現

   這里的后端代碼采用的是前一篇文章的代碼,只是多加了一些示例數據而已。具體的后端實現代碼為:

/// <summary> /// Web API 服務,為Web前端提供數據服務 /// </summary> public class TaskController : ApiController {  private readonly TaskRepository _taskRepository = TaskRepository.Current;  public IEnumerable<Task> 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;  } }/// <summary> /// 任務倉儲,封裝了所有關于數據庫的操作 /// </summary> public class TaskRepository {  #region Static Filed  private static Lazy<TaskRepository> _taskRepository = new Lazy<TaskRepository>(() => new TaskRepository());  public static TaskRepository Current  {   get { return _taskRepository.Value; }  }  #endregion  #region Fields  private readonly List<Task> _tasks = new List<Task>()  {   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<Task> GetAll()  {   return _tasks;  }  public IEnumerable<Task> 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";}<div id="list2"><h2>分頁第二種實現方式――任務列表</h2><div class="table-responsive"><table class="table table-striped"><thead><tr><th>編號</th><th>名稱</th><th>描述</th><th>負責人</th><th>創建時間</th><th>完成時間</th><th>狀態</th></tr></thead><tbody data-bind="foreach:pagedList"><tr><td data-bind="text: id"></td><td><a data-bind="text: name"></a></td><td data-bind="text: description"></td><td data-bind="text: owner"></td><td data-bind="text: creationTime"></td><td data-bind="text: finishTime"></td><td data-bind="text: state"></td></tr></tbody><tbody data-bind="if: loadingState"><tr><td colspan="8" class="text-center"><img width="60" src="/images/loading.gif" /></td></tr></tbody><tfoot data-bind="ifnot:loadingState"><tr><td colspan="8"><div class="pull-right"><div>總共有<span data-bind="text: totalCount"></span>條記錄, 每頁顯示:<span data-bind="text: pageSize"></span>條</div><div><ul class="pagination"><li data-bind="css: { disabled: pageIndex() === 1 }"><a href="#" data-bind="click: previous">«</a></li></ul><ul data-bind="foreach: allPages" class="pagination"><li data-bind="css: { active: $data.pageNumber === ($root.pageIndex()) }"><a href="#" data-bind="text: $data.pageNumber, click: function() { $root.gotoPage($data.pageNumber); }"></a></li></ul><ul class="pagination"><li data-bind="css: { disabled: pageIndex() === pageCount }"><a href="#" data-bind="click: next">»</a></li></ul></div></div></td></tr></tfoot></table></div></div> 

  對應的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() < 1)self.pageIndex(1);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 <= data.pageCount; i++) {//裝填頁碼self.allPages.push({ pageNumber: i });}//for...in 語句用于對數組或者對象的屬性進行循環操作。//for ... in 循環中的代碼每執行一次,就會對數組的元素或者對象的屬性進行一次操作。for (var i in data.pagedData) {//裝填數據self.pagedList.push(data.pagedData[i]);}}, 'GetByPaged', { 'pageIndex': self.pageIndex() });};//請求第一頁數據this.first = function() {self.pageIndex(1);self.refresh();};//請求下一頁數據this.next = function() {self.pageIndex(this.pageIndex() + 1);self.refresh();};//請求先前一頁數據this.previous = function() {self.pageIndex(this.pageIndex() - 1);self.refresh();};//請求最后一頁數據this.last = function() {self.pageIndex(this.pageCount() - 1);self.refresh();};//跳轉到某頁this.gotoPage = function (data, event) {self.pageIndex(data);self.refresh();};};function sendAjaxRequest(httpMethod, callback, url, reqData) {$.ajax("/api/task" + (url ? "/" + url : ""), {type: httpMethod,success: callback,data: reqData});}$(document).ready(function () {var viewModel = new ListViewModel2();viewModel.refresh();if ($('#list2').length)ko.applyBindings(viewModel, $('#list2').get(0));}); 

  這里介紹了下使用KnockoutJs實現分頁功能的實現思路:

1.頁面加載完成之后,發起Ajax請求去異步調用REST 服務來請求部分數據。

2.然后將請求的數據通過KnockoutJs綁定顯示。

3.將對應的分頁信息綁定到Bootstrap分頁中

4.當用戶點擊翻頁時,再發起一個Ajax請求去異步調用Rest服務請求數據,再將請求的數據顯示出來。

  這上面是描述的代碼的調用邏輯關系,你可以參考對應的JS代碼來理解上面的描述。到此我們第二種實現方式就實現完成了。

2.2 第一次加載所有數據,然后將所有數據分頁顯示

  接下來就介紹了第一種實現方式,這樣的實現方式,用戶只會在第一次的時候才會感覺到數據加載中,翻頁過程中感覺不到頁面的加載,這樣對于一些本身數據了不是太多的情況下,對于用戶的感覺也是更加流暢的。

  其具體的實現思路,也就是將請求的數據不要全部顯示在頁面上,因為數據太多,一下子顯示到頁面中,用戶可能會眼花繚亂。將數據分頁顯示將使得用戶查看更加清晰。

具體的Web前端Js的實現代碼為:

var ListViewModel = function () {var self = this;window.viewModel = self;self.list = ko.observableArray();self.pageSize = ko.observable(3); self.pageIndex = ko.observable(0); //要訪問的頁碼self.totalCount = ko.observable(1); //總記錄數self.loadingState = ko.observable(true);self.pagedList = ko.dependentObservable(function () {var size = self.pageSize();var start = self.pageIndex() * size;return self.list.slice(start, start + size);});self.maxPageIndex = ko.dependentObservable(function () {return Math.ceil(self.list().length / self.pageSize()) - 1;});self.previousPage = function () {if (self.pageIndex() > 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";}<div id="list"><h2>任務列表</h2><div class="table-responsive"><table class="table table-striped"><thead><tr><th>編號</th><th>名稱</th><th>描述</th><th>負責人</th><th>創建時間</th><th>完成時間</th><th>狀態</th></tr></thead><tbody data-bind="foreach:pagedList"><tr><td data-bind="text: id"></td><td><a data-bind="text: name"></a></td><td data-bind="text: description"></td><td data-bind="text: owner"></td><td data-bind="text: creationTime"></td><td data-bind="text: finishTime"></td><td data-bind="text: state"></td></tr></tbody><tbody data-bind="if:loadingState"><tr><td colspan="8" class="text-center"><img width="60" src="/images/loading.gif" /></td></tr></tbody><tfoot data-bind="ifnot:loadingState"><tr><td colspan="8"><div class="pull-right"><div>總共有<span data-bind="text: totalCount"></span>條記錄, 每頁顯示:<span data-bind="text: pageSize"></span>條</div><div><ul class="pagination"><li data-bind="css: { disabled: pageIndex() === 0 }"><a href="#" data-bind="click: previousPage">«</a></li></ul><ul data-bind="foreach: allPages" class="pagination"><li data-bind="css: { active: $data.pageNumber === ($root.pageIndex() + 1) }"><a href="#" data-bind="text: $data.pageNumber, click: function() { $root.moveToPage($data.pageNumber-1); }"></a></li></ul><ul class="pagination"><li data-bind="css: { disabled: pageIndex() === maxPageIndex() }"><a href="#" data-bind="click: nextPage">»</a></li></ul></div></div></td></tr></tfoot></table></div></div> 

三、運行效果

  接下來,讓我們看看,使用KnockoutJs實現的分頁效果:

四、總結

  到這里,本文要介紹的內容就結束,盡管本文實現的內容相對比較簡單,但是對于一些剛接觸KnockoutJs的朋友來說,相信本文的實現會是一個很多的指導。接下來,我將會為大家分享下AngularJs的相關內容。

以上所述是小編給大家介紹的Bootstrap與KnockoutJs相結合實現分頁效果實例詳解,希望對大家有所幫助!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 日本aaaa片毛片免费观看视频 | 黄视频网站免费观看 | 精品一区二区三区在线观看视频 | 手机国产乱子伦精品视频 | 国产精品久久久久久久久久iiiii | 亚洲精品在线观看免费 | 中文字幕www. | 精品国产91久久久久 | 黄色片视频观看 | av电影免费观看 | 91精品国产综合久久婷婷香蕉 | 久久影院免费观看 | 成人男女啪啪免费观看网站四虎 | 日本欧美在线播放 | 久久国产一二三 | 精国产品一区二区三区 | 欧洲黄色一级视频 | 羞羞视频免费视频欧美 | chinesexxxx极品少妇 | 亚洲人成综合第一网 | 国产日韩欧美一区 | 久草在线观看福利视频 | 免费国产一级淫片 | 午夜激情视频免费 | 国产一区精品在线观看 | 国产免费福利视频 | 九九视屏 | 国产精品久久久久久久久久iiiii | 嗯~啊~用力~高h | 麻豆一区二区99久久久久 | 国产精品视频成人 | 一级国产电影 | 天堂在线中文资源 | 精品欧美一区二区精品久久 | 天天艹综合 | 国产精品区一区二区三区 | 久久久久久久久久亚洲精品 | 日朝毛片| 欧美日韩电影在线 | 99亚洲伊人久久精品影院红桃 | 91精品国产91|