Knockoutjs ist ein JavaScript-implementiertes MVVM-Framework. Sehr gut. Nach dem Zugabe oder Verringern der Listendatenelemente müssen beispielsweise nicht das gesamte Steuerfragment aktualisiert oder JS -Additions- und Löschknoten selbst geschrieben werden. Definieren Sie einfach die Vorlage und Attribute, die ihre Syntaxdefinitionen entsprechen. Einfach ausgedrückt, wir müssen nur auf den Zugriff auf Daten achten.
1. Einführung
Da das System des Unternehmens in letzter Zeit überarbeitet werden muss, habe ich vor, KnockoutJs zu verwenden, um ein Web-Front-End für das überarbeitete neue System zu erstellen. Während des Prozesses stieß ich auf ein Problem - wie man KnockoutJs verwendet, um die Paginierungsfunktion zu vervollständigen. Im vorherigen Artikel wird KnockoutJS nicht vorgestellt, um die Pagination zu implementieren. In diesem Artikel wird in diesem Artikel KnockoutJS + Bootstrap zur Implementierung der Paginierungsanzeige verwendet.
2. Verwenden Sie KnockoutJs, um Pagination umzusetzen
Es gibt zwei Möglichkeiten, Paging zu implementieren. Das erste besteht darin, alle Daten zu laden und dann alle Daten auf Seiten anzuzeigen. Die zweite besteht darin, jedes Mal nur einen Teil der Daten zu laden und die nachfolgenden Daten jedes Mal neu zu laden.
Für diese beiden Methoden verwendet die mit der Razor-Methode implementierte Pagination im Allgemeinen die zweite Methode zur Implementierung der Pagination, aber für einseitige Programme hat die erste Implementierung auch ihre Vorteile. Für nicht sehr große Datenmengen kann die erste Implementierungsmethode verwendet werden, da die nachfolgende Datenbelastung auf diese Weise sehr reibungslos ist. Hier werden wir diese beiden Implementierungsmethoden separat vorstellen.
2.1 Implementierung von Teildatenbelastungen jedes Mal
Der Backend -Code hier verwendet den Code aus dem vorherigen Artikel, fügt jedoch einige Beispieldaten hinzu. Der spezifische Backend -Implementierungscode lautet:
/// <summary> /// Web-API-Dienst, Bereitstellung von Datendiensten für das Web Front-end /// </summary> öffentlicher Klasse 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) .Ondby (a => a.id); var pagedata = new pagedModel () {pageIndex = pageIndex, pagedData = tasks.tolist (), TotalCount = TotalCount, PageCount = (TotalCount+ PageSize -1) / PageSize}; // Daten zurückgeben, die pagedata zurücksendet; }} /// <summary> /// Task -Repository, verkörpert alle Vorgänge über die Datenbank /// </summary> public class taskrepository {#region static eingereichtes privates statisches 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 = "Create a SPA program", Description = "SPA(single page web application), The advantage of SPA is a small amount of bandwidth and a smooth experience", Owner = "Learning hard", FinishTime = DateTime.Parse(DateTime.Now.AddDays(1).ToString(CultureInfo.InvariantCulture)) }, new Task { Id =2, Name = "Learning KnockoutJs", Description = "KnockoutJs is an MVVM class library that supports two-way binding", Owner = "Tommy Li", FinishTime = Datetime.parse (datetime.now.adddays (2) .toString (CultureInfo.invariantCulture))}, neue Aufgabe {id = 3, name = "Learn AngularJs", Beschreibung = "Angularjs ist ein MVVM -Framework, das MVVM und MVC integriert. Datetime.parse (datetime.now.adddays (3) .toString (CultureInfo.invariantCulture)}, neue Task {id = 4, name = "Lernen Sie ASP.NET MVC -Website", Beschreibung Projekt und kann die Ausführungszeit jedes Links der Codeausführung ausgeben. Datetime.parse (datetime.now.adddays (5) .toString (CultureInfo.invariantCulture))}, neue Aufgabe {id = 6, name = "test task 2", Beschreibung = "Test Task 2", Eigentümer = "Li Zhi", Finishtime = Datetime.parse (datetime.now.adddays (6) .toString (CultureInfo.invariantCulture))}, neue Aufgabe {id = 7, name = "test task 3", Beschreibung = "Testaufgabe 3", Eigentümer = "Li Zhi", FinishTime = Finishime = Datetime.parse (datetime.now.adddays (7) .toString (CultureInfo.invariantCulture))},}; #endregion #region public Methodien public iEnumerable <Task> getAll () {return _tasks; } public iEnumerable <Task> getAll (int pageNumber, int pageSize, out int TotalCount) {var slip = (pageNumber - 1) * pageSize; var take = pageSize; TotalCount = _tasks.count; return _tasks.skip (überspringen). Take (take); } öffentliche Aufgabe get (int id) {return _tasks.find (p => p.id == id); } public Task add (Task -Element) {if (item == null) {neue argumentNulLexception ("item"); } item.id = _tasks.count + 1; _tasks.add (item); Gegenstand zurückgeben; } public void remove (int id) {_tasks.removeall (p => p.id == id); } public bool update (Aufgabeelement) {if (item == null) {neue argumentNulLexception ("item"); } var taskitem = get (item.id); if (taskitem == null) {return false; } _tasks.remove (TaskItem); _tasks.add (item); zurückkehren; } #endregion}Web-Front-End-Implementierungscode:
@{ViewBag.Title = "Index2";Layout = "~/Views/Shared/_Layout.cshtml";}<div id="list2"><h2>The second implementation method of pagination-task list</h2><div><table><thead><tr><th>number</th><th>name</th><th>description</th><th>person in Ladung </th> <Th> Erstellungszeit </th> <th> Vollständige Zeit </th> <Th> Status </th> </tr> </behandeln> <tbody data-bind = "foreach: pagedlist"> <tr> <td daten-bind = "text: id"> </td> <td> <a data-bind = "text" text "text" text "> </a> </td> </td> <td Beschreibung "> </td> <td daten-bind =" text: besitzer "> </td> <td data-bind =" text: creation time "> </td> <td data-Bind =" text: findzeit "> </td> <td data-bind =" text: Status "> </td> </tr> </tbody> <tbody-<tbody-<tbody-<tbody-ida-bind. colspan = "8"> <img src = "/bilder/laden.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot: ladeingState"> <tr> <tr> <td colspan = "8"> <div> <diven. Data-Bind = "text: pageSize"> </span> Datensätze </div> <ul> <li data-bind = "CSS: {deaktiviert: pageIndex () === 1}"> <a href = "#" data-bind = "click: vorher"> «</a> </li> </ul> <ul> <ul> <ul. ul. uld =" ca-bind = "foreach:" foreach: $ data.pagenumber === ($ root.pageIndex ())} "> <a href ="#"data-bind =" text: $ data.pageNumber, klick: function () {$ root.gotopage ($ data.pageNumber); pagecount} "> <a href ="#"data-bind =" klicken: Weiter ">» </a> </li> </ul> </div> </div> </td> </tfoot> </table> </div> </div>Die entsprechende JS -Implementierung lautet:
// Die zweite Möglichkeit zur Implementierung von Paging var listViewModel2 = function () {// ViewModel selbst. Wird verwendet, um die Verwirrung des Bereichs zu verhindern, wenn dieses direkt var self = this verwendet wird; self.loadingState = ko.Observable (true); self.pageSize = Ko.OBServable (3); // Data this.pagedList = ko.observablearray (); // Die Seitenzahl zugänglich ist. Aktuelle Seite this.currengepage = ko.Observable (1); self.totalCount = ko.observable (1); this.refresh = function () {// Die Anforderungsseitennummer in der Datenseitennummer einschränken, wenn (self.pageIndex () self.pageIndex (1); if (self.pageIndex ()> selfageCount () {self -poydex (selfageIndex (selfagex) (selfagex (selfagex) (selfagex (selfagex) (). sendajaxRequest ("get", function (data) {// Vor dem Laden neuer Daten die ursprünglichen Daten selbst. i ++) {// Seitennummer Self.Allpages.push ({Pagenumber: I});} // In Anweisung wird die Eigenschaften eines Arrays oder Objekts verwendet. self.pagedList.push (data.pagedData [i]);}}, 'getBypaged', {'pageIndex': self.pageIndex ()};}; // anfordern Sie die erste Seite der Daten an, first = function () {self.pageIndex (1); {self.pageIndex(this.pageIndex() + 1);self.refresh();};//Request the previous page of data this.previous = function() {self.pageIndex(this.pageIndex() - 1);self.refresh();};//Request the last page of data this.last = function() {self.pageIndex(this.pageCount() - 1); self.refresh ();}; // Umleiten Sie zu einer bestimmten Seite this.gotopage = function (Daten, Ereignis) {self.pageIndex (Daten); self.refresh ();};};}; Funktion sendajaxRequest (httpMethod, callback, url, reqdata) {$ .ajax ("/api/task" + (url? "/" + url: ""), {type: httpMethod, Erfolg: Rückruf, Daten: reqdata});} $ (Dokument). ListViewModel2 (); viewModel.refresh (); if ($ ('#list2'). Länge) Ko.applybindings (ViewModel, $ ('#list2'). Get (0));});Hier finden Sie eine Einführung in die Implementierungsidee, KnockoutJs zur Implementierung der Paginationsfunktion zu verwenden:
1. Nachdem die Seite geladen wurde, initiieren Sie eine AJAX -Anfrage, um den REST -Dienst asynchron anzurufen, um einen Teil der Daten anzufordern.
2. Zeigen Sie dann die angeforderten Daten über die KnockoutJS -Bindung an.
3. Binden Sie die entsprechenden Paging -Informationen an den Bootstrap Paging
V.
Dies ist die logische Beziehung des oben beschriebenen aufrufenden Code. Sie können sich auf den entsprechenden JS -Code beziehen, um die obige Beschreibung zu verstehen. Zu diesem Zeitpunkt ist unsere zweite Implementierungsmethode abgeschlossen.
2.2 Laden Sie alle Daten zum ersten Mal und zeigen Sie dann alle Datenpaging an
Als nächstes werden wir die erste Implementierungsmethode vorstellen. Bei dieser Implementierungsmethode sind Benutzer nur das Gefühl, dass die Daten zum ersten Mal geladen werden, und sie spüren nicht, wie die Seite während des Seitenverlaufs geladen wird. Auf diese Weise fühlen sich Benutzer reibungsloser, wenn in einigen Fällen nicht zu viele Daten vorhanden sind.
Die spezifische Implementierungsidee besteht darin, nicht alle angeforderten Daten auf der Seite anzuzeigen, da zu viele Daten vorhanden sind und diese auf der Seite gleichzeitig angezeigt werden und Benutzer möglicherweise geblendet werden. Durch das Anzeigen von Daten Paging werden Benutzer klarer angezeigt.
Der spezifische Implementierungscode von Web Front-End JS lautet:
var listViewModel = function () {var self = this; window.viewModel = self; self.list = ko.obserservablearray (); self.pageSize = ko.observable (3); self.pageIndex = ko.Observable (0); // auf die Seitennummer auf self zugreifen. // Gesamtzahl der Datensätze 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. 1);}}; self.Allpages = ko.DependentObServable (function () {var pages = []; für (var i = 0; i <= self.maxPageIndex (); i ++) {Pages.push ({pageNumber: (i+1)}); {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'). Länge) Ko.ApplyBindings (ListViewModel, $ ('#list'). get (0));}, null, null);} $ (document) .ready (function () {BindViewModel ();});Die Implementierung seiner Front-End-Seite ähnelt der vorherigen Implementierung. Der spezifische Seitencode lautet wie folgt:
@{ViewBag.Title = "Index";Layout = "~/Views/Shared/_Layout.cshtml";}<div id="list"><h2>Task List</h2><div><table><thead><tr><th>Number</th><th>Name</th><th>Description</th><th>People in charge</th><th>Creation Zeit </Th> <Th> Abschlusszeit </th> <th> statu </th> </tr> </tbody data-bind = "foreach: pagedlist"> <tr> <td data-bind = "text: id"> </td> <td> <a data-bind = "text: name"> </a> </td> <td> <td> <td> <tddaten-text: Data-Bind = "Text: Eigentümer"> </td> <td data-bind = "text: creationtime"> </td> <td data-bind = "text: Finishime"> </td> <td data-bind = "text: Status: Zustand"> </td> </tr> </tbody> <tbody Data-bind = "if: loadingState"> <tddy "<tby src = "/images/lade.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot: loadingState"> <tr> <td colspan = "8"> <div> <div> <div> Es gibt eine Gesamtzahl von <span daten-bind = "Text: TotalCount"> </</</</</</</</</</</</</</</</</</</</</</Zu Aufzeichnungen, und jede Seite wird angezeigt. PageSize "> </span> Datensätze </div> <div> <ul> <li data-bind =" CSS: {deaktiviert: pageIndex () === 0} "> <a href ="#"data-bind =" click: vorher: VorherigerPage ">« </a> </li> </ul> <ul> <ula-bind. $ data.pagenumber === ($ root.pageIndex () + 1)} "> <a href ="#"data-bind =" text: $ data.pagenumber, klick: function () {$ root.movetopage ($ data.pagenumber-1); === maxpageIndex ()} "> <a href ="#"data-bind =" klicken: NextPage ">» </a> </li> </ul> </div> </div> </td> </tr> </tfoot> </table> </tiv> </div> </div> </td> </tr> </tfoot> </tiv> </div> </div> </div>3. Betriebseffekt
Schauen wir uns als nächstes den Paginationseffekt an, der mit KnockoutJs implementiert wird:
4. Zusammenfassung
Zu diesem Zeitpunkt ist der in diesem Artikel eingeführte Inhalt vorbei. Obwohl der in diesem Artikel implementierte Inhalt relativ einfach ist, glaube ich für einige Freunde, die neu in KnockoutJs sind, dass die Implementierung dieses Artikels eine Menge Anleitung sein wird. Als nächstes werde ich Ihnen den relevanten Inhalt von AngularJs mitteilen.
Das obige ist eine detaillierte Erklärung der Beispiele für die Kombination von Bootstrap mit KnockoutJs, um Paginationseffekte zu erzielen, die der Editor Ihnen vorgestellt hat. Ich hoffe, es wird für Sie hilfreich sein!