利用Bootstrap Paginator外掛和knockout.js

neuyu發表於2021-09-09

在最近一個專案中,需要結合一堆條件查詢並對查詢的結果資料完成一個簡單分頁功能,可是做著做著,自己的思路越來越模糊,做到心態崩潰!!! 哈哈

特此花點時間重新總結,並從最簡單的分頁,然後向多條件查詢分頁慢慢過渡,或許有人覺得這個很簡單(可以繞道啦,哈哈),卻是對基礎知識的一次學習過程。

Demo地址:

本文地址:https://www.cnblogs.com/CKExp/p/9218904.html

 

一、環境介紹

  分頁功能很多已有的很完美的外掛或是第三方應用包都能夠完美實現,我在此利用了一些前端外掛來完成分頁功能。

  前端的外掛完成前端分頁數字之類的切換展示;

  利用外掛完成分頁資料的繫結;

  在後端,利用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的地址:

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4550/viewspace-2803529/,如需轉載,請註明出處,否則將追究法律責任。

相關文章