Knockoutjsは、JavaScriptが実装されたMVVMフレームワークです。とても良い。たとえば、リストデータ項目を追加または削減した後、コントロールフラグメント全体を更新したり、JSの追加と削除ノードを自分で書き留める必要はありません。構文定義を満たすテンプレートと属性を定義するだけです。簡単に言えば、データへのアクセスに注意を払う必要があります。
1。はじめに
同社のシステムは最近刷新する必要があるため、NockoutJSを使用して、改良された新しいシステムのWebフロントエンドを作成する予定です。プロセス中に、問題に遭遇しました - knockoutjsを使用してページネーション関数を完了する方法。前の記事では、knockoutjsはページネーションを実装するために導入されていないため、この記事では、knowoutjs + bootstrapを使用して、データのページネーションディスプレイを実装します。
2。ノックアウトJSを使用して、ページネーションを実装します
ページングを実装するには2つの方法があります。 1つ目は、すべてのデータをロードしてから、すべてのデータをページに表示することです。 2つ目は、毎回データの一部のみをロードし、その後のデータを毎回リロードすることです。
これら2つの方法では、Razorメソッドを使用して実装されたページネーションは一般に、ページネーションを実装するために2番目の方法を採用しますが、単一ページプログラムには、最初の実装にも利点があります。大量のデータではない場合、最初の実装方法を使用できます。このようにして、後続のデータロードは非常にスムーズになるためです。したがって、ここでは、これら2つの実装方法を個別に紹介します。
2.1毎回部分データ読み込みの実装
ここのバックエンドコードは、前の記事のコードを使用しますが、データの例を追加します。特定のバックエンド実装コードは次のとおりです。
/// <summary> /// Web APIサービス、Webフロントエンドにデータサービスを提供する/// public iEnumerable <cask> 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}; //データを返します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 #region fields private readonly list <task> _tasks = new list <cask>(){new Task {id = 1、name = "create a spa program"、description = "spa(シングルページWebアプリケーション)、スパの利点は少量の帯域幅とスムーズな経験です" datetime.parse(datetime.now.adddays(1).tostring(cultureinfo.invariantculture)}、new task {id = 2、name = "Learning nockoutjs"、 "nockoutjsは、2方向バインディングをサポートするMVVMクラスライブラリです。 datetime.parse(datetime.now.adddays(2).tostring(cultureinfo.invariantculture)}、new task {id = 3、name = "Learn Angularjs"、 "AngularjsはMVVMフレームワークです。 datetime.parse(datetime.now.adddays(3).tostring(cultureinfo.invariantculture)}、new task {id = 4、 "Learn asp.net MVC Webサイト"、description = "glimpseは.netの下でのパフォーマンステストツールです。元のプロジェクト、およびコード実行の各リンクの実行時間を出力することができます」、所有者= "Tonny li"、finishtime.parse(datetime.now.adddays(4).toString(cultureinfo.invariantculture))}、新しいタスク{id = 5、name = "test =" tesction = "" tesction 1 " datetime.parse(datetime.now.adddays(5).tostring(cultureinfo.invariantculture))}、new task {id = 6、name = "test task 2"、 "test =" test task 2 "、owner =" li zhi "、finishtime = datetime.parse(datetime.now.adddays(6).tostring(cultureinfo.invariantculture)}、new task {id = 7、name = "test task 3"、 "test =" test task 3 "、所有者=" li zhi "、finishtime = datetime.parse(datetime.now.adddays(7).tostring(cultureinfo.invariantculture)}、}; #endregion #region public method public ienumerable <task> getall(){return _tasks; } public iEnumerable <cask> 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){new argumentnullexception( "item"); } item.id = _tasks.count + 1; _tasks.add(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); trueを返します。 } #endregion}Webフロントエンドの実装コード:
@{viewbag.title = "index2"; layout = "〜/views/shared/_layout.cshtml";} <div id = "list2"> <h2>ページネーションタスクの2番目の実装方法</h2> <> <div> <table> <thead> <th </th </th </th </th </th </th </th </th </th </th </th </th </th </th </th </th </th> Charge </th> <th>作成時間</th> <th>完全な時間</th> <th>ステータス</th> </tr> </tr> </tread> <tbody data-bind = "foreach:pagelist"> <tr> <td data-bind = "text:id"> </td> <td> <a data-bind = "text:"> </a> </td> <td>説明 "> </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 bind = colspan = "8"> <img src = "/images/loading.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot:loadingstate"> <tr> <td colspan = "8"> <div> <div> data-bind = "text:pagesize"> </span> records </div> <div> <ul> <li data-bind = "css:{disabled:pageindex()=== 1}"> <a href = "#" data-bind = "click:click:click:click:前">«</a> </li> </ul> <ul-bind = " $ data.pageNumber ===($ root.pageIndex()} "> <a href ="# "data-bind =" text:$ data.pageNumber、click(){$ root.gotopage($ data.pageNumber)} "> </a> </li> pagecount} "> <a href ="# "data-bind =" click:next ">»</a> </li> </ul> </div> </div> </td> </tfoot> </table> </div> </div>対応するJS実装は次のとおりです。
//ページングvar listviewmodel2 = function(){// viewmodel自体を実装する2番目の方法。これを直接使用するときの範囲の混乱を防ぐために使用されますvar self = this; self.loadingState = ko.observable(true); self.pagesize = ko.observable(3); // data this.pagedlist = ko.observablearray(); //ページ番号にアクセスするページ番号this.pageindex = ko.observable(1); // page of page of this.pagecount = ko.observable(1);ページ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.pagecount(); sendajaxrequest( "get"、function(data){//新しいデータをロードする前に、self.pagedlist.removeall(); self.allpages.removeall(); self.totalcount(data.totalcount); self.pagecount(data.pagecount); self(fals); fils(fals); fils(data.pagecount); i ++){//ページ番号self.allpages.push({pageNumber:i}); // ... for ... for ... for ... for ... for for ... self.pagedlist.push(data.pageddata [i]);}}、 'getBypaged'、{'pageindex':self.pageindex()} {self.pageIndex(this.pageIndex() + 1); self.refresh();}; //データの前のページをリクエストof.previous = function(){self.pageIndex()(this.pageIndex() - 1); self.refresh();}; 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、httpmethod、httpmethod、httpmethod、httpmethod、httpmethod、httpmethod、httpmethod、httpmethod、callback、data:reqdata}); listViewModel2(); ViewModel.Refresh(); if($( '#list2')。length)ko.applybindings(viewmodel、$( '#list2')。get(0));});knockoutjsを使用してページネーション関数を実装するという実装のアイデアの紹介を次に示します。
1。ページが読み込まれたら、AJAXリクエストを開始して、データの一部を要求するためにRESTサービスを非同期に呼び出します。
2。次に、NockoutJSバインディングを介して要求されたデータを表示します。
3。対応するページング情報をブートストラップページングにバインドします
4.ユーザーがクリックしてページをターンしたら、AJAXリクエストを開始して、RESTサービスを非同期に呼び出し、要求されたデータを表示します。
これは、上記の呼び出しコードの論理的な関係です。対応するJSコードを参照して、上記の説明を理解できます。この時点で、2番目の実装方法が完了します。
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(){untersize(){return math.ceil() 1;}); self.previouspage = function(){if(self.pageindex()> 0){self.pageindex(self.pageindex() - 1);}}; self.nextpage = function(){if(self.pageindex()<self.maxpageindex()){self.pageindex() + pageindex() + pageindex() + pageindex() 1);}}; self.allpages = ko.dependentobservable(function(){var i = 0; i <= self.maxpageindex(); i ++){pageNumber:(i+1)});} pages;} {self.pageIndex(index);};}; var listViewmodel = new listViewModel(); function bindviewmodel(){sendajaxrequest( "get"、function(data){listviewmodel.loadingState(false); listViewmodel.List(data); listViewmodel.Totalcount(data); ($( '#list')。長さ)ko.applybindings(listviewmodel、$( '#list')。get(0));}、null、null);} $(document).read(function(){bindviewmodel();});フロントエンドページの実装は、以前の実装に似ています。特定のページコードは次のとおりです。
@{viewbag.title = "index"; layout = "〜/views/shared/_layout.cshtml";} <div id = "list"> <h2>タスクリスト</h2> <div> <table> <thead> <tr> <> number </th> <th> </th </th </th>時間</th> <th>完了時間</th> <th> statu </th> </tr> </tbody data-bind = "foreach:pagelist"> <tr> <td data-bind = "text:id"> </td> <td> data-bind = "text:所有者"> </td> <td data-bind = "text:creationtime"> </td> <td data-bind = "text:finishtime"> </td> <td data-bind = "text:state:state"> </td> </tr> </tbody> <tbody> <tbody data-bind = " src = "/images/loading.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot:loadingstate"> <tr> <td colspan = "8"> <div> div>レコード</div> <div> <ul> <li data-bind = "css:{disabled:pageindex()=== 0}"> <a href = "#" data-bind = "click:click>«</a> </li> </ul> <ul data-bind =" ($ root.pageIndex() + 1)} "> <a href =" data-bind = "text:$ data:click(){$ root.movetopage($ data.pageNumber-1)}" } "> <a href ="# "data-bind =" click:nextpage ">»</a> </li> </ul> </div> </div> </td> </tr> </tfoot> </table> </tiv> </div>3。操作効果
次に、Knockoutjsを使用して実装されたページネーション効果を見てみましょう。
4。概要
この時点で、この記事で紹介されるコンテンツは終わりました。この記事で実装されているコンテンツは比較的簡単ですが、knockoutjsに慣れていない友人にとっては、この記事の実装が多くのガイダンスになると思います。次に、Angularjsの関連コンテンツを共有します。
上記は、編集者が紹介したページネーション効果を実現するために、ブートストラップをknockoutjsと組み合わせる例の詳細な説明です。それがあなたに役立つことを願っています!