Knockoutjs est un framework MVVM implémenté par JavaScript. Très bien. Par exemple, après avoir ajouté ou diminué les éléments de données de liste, il n'est pas nécessaire de rafraîchir l'ensemble du fragment de contrôle ou d'écrire des nœuds JS et de suppression par vous-même. Définissez simplement le modèle et les attributs qui répondent à ses définitions de syntaxe. Autrement dit, nous avons seulement besoin de prêter attention à l'accès aux données.
1. Introduction
Étant donné que le système de l'entreprise doit être remanié récemment, je prévois d'utiliser KnockoutJS pour créer un Web frontal pour le nouveau système remanié. Pendant le processus, j'ai rencontré un problème - comment utiliser knockoutjs pour remplir la fonction de pagination. Dans l'article précédent, KnockoutJS n'est pas introduit pour implémenter une pagination, donc dans cet article, KnockoutJS + Bootstrap sera utilisé pour implémenter l'affichage de la pagination des données.
2. Utilisez des knockoutjs pour implémenter la pagination
Il existe deux façons de mettre en œuvre la pagination. Le premier consiste à charger toutes les données, puis à afficher toutes les données sur les pages; La seconde consiste à charger une partie des données à chaque fois et à recharger les données suivantes à chaque fois.
Pour ces deux méthodes, la pagination implémentée à l'aide de la méthode du rasoir adopte généralement la deuxième méthode pour mettre en œuvre la pagination, mais pour les programmes d'une seule page, la première implémentation a également ses avantages. Pour des quantités non très importantes de données, la première méthode d'implémentation peut être utilisée, car de cette manière, le chargement des données ultérieur sera très fluide. Nous allons donc introduire ces deux méthodes de mise en œuvre séparément.
2.1 Implémentation du chargement partiel des données à chaque fois
Le code backend utilise ici le code de l'article précédent, mais ajoute quelques exemples de données. Le code d'implémentation backend spécifique est:
/// <summary> /// Web API Service, fournissant des services de données pour le Web Front-End /// </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 ([Fruriri] 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}; // RETOUR DATA RETOUR PAGEDATA; }} /// <summary> /// Repository de tâche, encapsulant toutes les opérations sur la base de données /// </summary> classe publique TaskRepository {#Region Static Static 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 = "Create a Spa Program", Description = "Spa (application Web de page unique), L'avantage de Spa est une petite quantité de bande passante et une expérience fluide", propriétaire = "apprentissage dur", finitiontime = DateTime.Parse (DateTime.Now.Adddays (1) .ToString (CultureInfo.InvariantCulture))}, New Task {id = 2, name = "Learning KnockoutJs", Description = "KnockoutJs est une bibliothèque de classe MVVM = qui prend en charge la binding à deux voies", propriétaire = "tommy li", finaltimetime = DateTime.Parse (DateTime.Now.Adddays (2) .ToString (CultureInfo.InvariantCulture))}, New Task {id = 3, name = "Learn AngularJS", Description = "AngularJS est un cadre MVVM qui intègre MVVM et MVC avec un.", Propriétaire = "li zhi", finirtime = DateTime.Parse (DateTime.Now.Adddays (3) .ToString (CultureInfo.InvariantCulture))}, New Task {id = 4, Name = "Learn ASP.NET MVC SITE WEB", Description = "Glimpse est un outil de test de performance sous .net, qui prend en charge ASP.NET, ASP.NET MVC, EF, etc. Project, et peut sortir le temps d'exécution de chaque lien de l'exécution du code ", propriétaire =" Tonny Li ", Finishtime = DateTime.Parse (DateTime.Now.Adddays (4) .Tostring (CultureInfo.invariantCulture))}, New Task {id = 5, nom =" Test Task 1 "," Test Task 1 ", propriétaire =" li zhi ", finition = finition = DateTime.Parse (DateTime.Now.Adddays (5) .ToString (CultureInfo.InvariantCulture))}, nouvelle tâche {id = 6, name = "Test Task 2", Description = "Test Task 2", propriétaire = "Li Zhi", Finishtime = DateTime.Parse (DateTime.Now.Adddays (6) .ToString (CultureInfo.InvariantCulture))}, Nouvelle tâche {id = 7, name = "Test Task 3", Description = "Test Task 3", propriétaire = "Li Zhi", Finishtime = DateTime.Parse (DateTime.Now.Adddays (7) .ToString (CultureInfo.InvariantCulture))},}; #EndRegion #Region Méthodes publiques publiques 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 (prendre); } tâche publique get (int id) {return _tasks.find (p => p.id == id); } tâche publique add (élément de tâche) {if (item == null) {throw new argumentNullexception ("item"); } item.id = _tasks.Count + 1; _tasks.add (item); return item; } public void dissover (int id) {_tasks.removeall (p => p.id == id); } public bool update (élément de tâche) {if (item == null) {throw new argumentNullexception ("item"); } var taskItem = get (item.id); if (taskItem == null) {return false; } _tasks.remove (taskItem); _tasks.add (item); Retour Vrai; } #endregion}Code d'implémentation frontal Web:
@ {Viewbag.Title = "index2"; Layout = "~ / Views / Shared / _Layout.cshtml";} <div id = "list2"> <h2> La deuxième méthode d'implémentation de la liste de pagination </h2> <div> <pall Charge </th> <th> Temps de création </th> <th> Temps complet </th> <th> status </th> </tr> </ treat> <tbody data-bind = "foreach: pagedlist"> <tr> <td data-bind = "text: id"> </td> <td> <a data-bind = "text: name"> </a> </td> Description "> </td> <td data-bind =" text: propriétaire "> </td> <td data-bind =" text: Creationtime "> </td> <td data-bind =" text: finaltime "> </td> <td data-bind =" text: state "> </td> </ tr> </tody> <tbody data-bind = colspan = "8"> <img src = "/ images / charging.gif" /> </td> </tr> </ tbody> <tfoot data-bind = "ifnot: chargingstate"> <tr> <td ColSpan = "8"> <div> <div> Il y a un total de la page <spann-bind = "text: totalCount"> </panne>, et chaque page est affiché: Data-Bind = "Text: PageSize"> </span> enregistre </div> <div> <ul> <li data-bind = "css: {handicap $ data.pageNumber === ($ root.pageIndex ())} "> <a href =" # "data-bind =" text: $ data.pageNumber, cliquez: function () {$ root.gotopage ($ data.pageNumber); PageCount} "> <a href =" # "data-bind =" cliquez: net ">» </a> </li> </ul> </div> </div> </td> </tfoot> </ table> </div> </div>L'implémentation JS correspondante est:
// la deuxième façon d'implémenter le paginage var listViewModel2 = function () {// ViewModel lui-même. Utilisé pour éviter la confusion de la portée lors de l'utilisation directement de Var Self = ceci; self.loadingState = ko.Observable (true); self.pagesize = ko.observable (3); // data this.pagedlist = ko.observablearray (); // le numéro de page à accéder. ko.oBServableArray (); // la page actuelle this.currengepage = ko.observable (1); self.totalcount = ko.observable (1); this.refresh = function () {// restreignez le numéro de page de demande dans le numéro de page de données if (self.pageIndex () <1) self.pageIndex (1); if (self.pageIndex ()> self.pageCount ()) {sel.pageIndex (self.pageCount (); sendajaxRequest ("get", fonction (data) {// Avant de charger de nouvelles données, supprimez les données d'origine self.pagedList.removeall (); self.allpages.removeall (); self.totalCount (data.totalcount); self.pageCount (data.pageCount); Self.LeadingState (false); pour (var i = 1; i ++) {// Reload Page Number self.allPages.push ({PageNumber: i});} // pour ... dans l'instruction est utilisée pour faire bouger les propriétés d'un tableau ou d'un objet. data self.pagedlist.push (data.pageddata [i]);}}, 'getByPaged', {'pageIndex': self.pageIndex ()});}; // demande la première page de Data This.First = function () {self.pageIndex (1); Self.refresh ();}; // demande la page suivante de Data That. {self.pageIndex (this.pageIndex () + 1); self.refresh ();}; // demande la page précédente de Data This.Previous = function () {self.pageIndex (this.pageIndex () - 1); self.refresh ();}; // demande la dernière page de données this.Last = function () {self.page 1); self.refresh ();}; // rediriger vers une certaine page this.gotopage = function (data, event) {self.pageIndex (data); self.refresh ();};};}; function sendajaxRequest (httpMethod, callback, url, reqdata) {$ .ajax ("/ api / task" + (url? "/" + url: ""), {type: httpMethod. ListViewModel2 (); ViewModel.refresh (); if ($ ('# list2'). Length) ko.ApplyBindings (ViewModel, $ ('# list2'). Get (0));});Voici une introduction à l'idée de mise en œuvre d'utiliser KnockoutJS pour implémenter la fonction de pagination:
1. Une fois la page chargée, lancez une demande AJAX pour appeler le service de repos de manière asynchrone pour demander une partie des données.
2. Puis affichez ensuite les données demandées via la liaison KnockoutJs.
3. Liez les informations de pagination correspondantes à la pagination bootstrap
4. Lorsque l'utilisateur clique pour tourner la page, lancez une demande Ajax pour appeler le service de repos de manière asynchrone et afficher les données demandées.
Il s'agit de la relation logique du code d'appel décrit ci-dessus. Vous pouvez vous référer au code JS correspondant pour comprendre la description ci-dessus. À ce stade, notre deuxième méthode d'implémentation est terminée.
2.2 Chargez toutes les données pour la première fois, puis affichez toutes les données de données
Ensuite, nous présenterons la première méthode d'implémentation. Dans cette méthode d'implémentation, les utilisateurs n'auront que le chargement des données pour la première fois, et ils ne sentiront pas le chargement de la page pendant le processus de tournage de la page. Cela rendra les utilisateurs plus fluide lorsqu'il n'y a pas trop de données dans certains cas.
L'idée de mise en œuvre spécifique est de ne pas afficher toutes les données demandées sur la page, car il y a trop de données et elle sera affichée sur la page à la fois, et les utilisateurs peuvent être éblouis. L'affichage de la pagination de données rendra les utilisateurs plus clairs.
Le code d'implémentation spécifique de JS frontal est:
var listViewModel = function () {var self = this; window.viewModel = self; self.list = ko.observablearray (); self.pagesize = ko.observable (3); self.pageIndex = ko.observable (0); // le numéro de page à accéder à soi.TotalCount = ko.Observable (1); // Nombre total d'enregistrements self.loadingState = ko.Observable (true); self.pagedList = ko.dependendaBservable (function () {var size = self.pageSize (); var start = self.pageIndex () * size; return self.list.slice (start, start + size);}); self.maxpageIndex = ko.dependentObservable (fonction () {return Math.Ceil (self.List (). 1;}); self.PreviousPage = function () {if (self.pageIndex ()> 0) {self.pageIndex (self.pageIndex () - 1);}}; 1);}}; self.allPages = ko.dependendoBServable (function () {var pages = []; for (var i = 0; i <= self.maxpageIndex (); i ++) {pages.push ({pAGenumber: (i + 1)});} return pages;}); self.MoveToPage = furet (index); gens ($ ('# list'). Length) ko.ApplyBindings (listViewModel, $ ('# list'). get (0));}, null, null);} $ (document) .ready (function () {bindViewModel ();});L'implémentation de sa page frontale est similaire à l'implémentation précédente. Le code de page spécifique est le suivant:
@ {Viewbag.Title = "index"; Layout = "~ / Views / Shared / _layout.cshtml";} <div id = "list"> <h2> Liste des tâches </h2> <div> <Table> <Thead> <Tr> <th> Numéro </ Th> <th> Name </ Th> <th> Description </th> <th> Les gens en charge </ th> Créer Temps </th> <th> Temps d'achèvement </ 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 data-bind = "Text: Description"> </a> </td> <td Data-Bind = "Text: Description"> </a> </td> <td Data-Bind = "Text: Description"> </a> </td> <td Data-Bind = "Text: Description"> </a> </td> <td Data-BIND = " data-bind = "text: propriétaire"> </td> <td data-bind = "text: Creationtime"> </td> <td data-bind = "text: finmenttime"> </td> <td data-bind = "text: state"> </td> </tr> </ tbody> <tbody data-bind = "if: lodagestate"> <tr> <td Colspan = "8"> <imgg "> <tr> <td Colspan =" 8 "> <img src = "/ images / charging.gif" /> </td> </tr> </tbody> <tfoot data-bind = "ifnot: chargingstate"> <tr> <td colspan = "8"> <div> <div> Les enregistrements ont un total de <pan Data-Bind = "Text:" Text "> </spande>, et chaque page est affichée: <spann-bind =" Text: PageSize "> </span> enregistre </div> <div> <ul> <li data-bind =" css: {Disable $ data.pageNumber === ($ root.pageIndex () + 1)} "> <a href =" # "data-bind =" text: $ data.pageNumber, cliquez: function () {$ root.movetOpage ($ data.pageNumber-1); === MaxPageIndex ()} "> <a href =" # "data-bind =" click: nextPage ">» </a> </li> </ul> </div> </div> </td> </tr> </tfoot> </plow> </tiv> </v> </tr> </tfoot> </plow> </tiv> </v>3. Effet de fonctionnement
Ensuite, jetons un coup d'œil à l'effet de pagination mis en œuvre à l'aide de knockoutjs:
4. Résumé
À ce stade, le contenu à introduire dans cet article est terminé. Bien que le contenu mis en œuvre dans cet article soit relativement simple, pour certains amis qui sont nouveaux à KnockoutJ, je crois que la mise en œuvre de cet article sera beaucoup de conseils. Ensuite, je partagerai avec vous le contenu pertinent d'AngularJS.
Ce qui précède est une explication détaillée des exemples de combinaison de bootstrap avec les knockoutjs pour réaliser des effets de pagination que l'éditeur vous a introduits. J'espère que cela vous sera utile!