<strike id="5ntnv"><i id="5ntnv"><del id="5ntnv"></del></i></strike>
<strike id="5ntnv"></strike><ruby id="5ntnv"></ruby><del id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></del><strike id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></strike>
<strike id="5ntnv"></strike>
<strike id="5ntnv"></strike>
<span id="5ntnv"><dl id="5ntnv"></dl></span>
<strike id="5ntnv"><i id="5ntnv"><del id="5ntnv"></del></i></strike><th id="5ntnv"><noframes id="5ntnv"><span id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></span>
<span id="5ntnv"></span>
<strike id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></strike>
<strike id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></strike><strike id="5ntnv"><i id="5ntnv"></i></strike><span id="5ntnv"></span>
<strike id="5ntnv"></strike>
<strike id="5ntnv"></strike>
<th id="5ntnv"><noframes id="5ntnv">
<ruby id="5ntnv"></ruby>
<strike id="5ntnv"><dl id="5ntnv"></dl></strike>

貴州網站建設公司貴州網站建設公司

[后端人員耍前端系列]KnockoutJs篇:使用KnockoutJs+Bootstrap實現分頁

一、后端引言

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

二、后端使用KnockoutJs實現分頁

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

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

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

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

[后端人員耍前端系列]KnockoutJs篇:使用KnockoutJs+Bootstrap實現分頁 _ JavaClub全棧架構師技術筆記
/// <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    }
View Code

  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">&laquo;</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">&raquo;</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();   });

  其前端頁面的實現與前面的實現類似。具體頁面代碼如下:

[后端人員耍前端系列]KnockoutJs篇:使用KnockoutJs+Bootstrap實現分頁 _ JavaClub全棧架構師技術筆記
@{     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">&laquo;</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">&raquo;</a></li></ul>                            </div>                        </div>                    </td>                </tr>            </tfoot>        </table>    </div></div>
View Code

三、運行效果

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

 [后端人員耍前端系列]KnockoutJs篇:使用KnockoutJs+Bootstrap實現分頁 _ JavaClub全棧架構師技術筆記

四、總結

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

本文所有源碼實現:KnockoutJSPaged

 

如果您認為這篇文章還不錯或者有所收獲,您可以通過右邊的“打賞”功能打賞我一杯咖啡【物質支持】,也可以點擊右下角的【店長推薦】按鈕【精神支持】,因為這兩種支持都是我繼續寫作,分享的最大動力


[后端人員耍前端系列]KnockoutJs篇:使用KnockoutJs+Bootstrap實現分頁 _ JavaClub全棧架構師技術筆記[后端人員耍前端系列]KnockoutJs篇:使用KnockoutJs+Bootstrap實現分頁 _ JavaClub全棧架構師技術筆記

作者:Learning hard
來源鏈接:https://www.cnblogs.com/zhili/p/KnockoutJsPaged.html

贊(1242)
未經允許不得轉載:>貴州網站建設公司 » [后端人員耍前端系列]KnockoutJs篇:使用KnockoutJs+Bootstrap實現分頁
国产欧美精品