KnockoutJS es un marco MVVM implementado con JavaScript. Muy bien. Por ejemplo, después de agregar o disminuir los elementos de datos de la lista, no es necesario actualizar todo el fragmento de control o escribir nodos de adición y eliminación de JS por sí mismo. Simplemente defina la plantilla y los atributos que cumplen con sus definiciones de sintaxis. En pocas palabras, solo necesitamos prestar atención al acceso a los datos.
1. Introducción
Dado que el sistema de la compañía necesita ser renovado recientemente, planeo usar knockoutjs para crear un front-end web para el nuevo sistema renovado. Durante el proceso, encontré un problema: cómo usar knockoutjs para completar la función de paginación. En el artículo anterior, no se introduce KnockoutJS para implementar la paginación, por lo que en este artículo, KnockoutJS + Bootstrap se utilizará para implementar la visualización de datos de la paginación.
2. Use knockoutjs para implementar la paginación
Hay dos formas de implementar la paginación. El primero es cargar todos los datos y luego mostrar todos los datos en las páginas; El segundo es cargar solo parte de los datos cada vez, y recargar los datos posteriores cada vez.
Para estos dos métodos, la paginación implementada utilizando el método Razor generalmente adopta el segundo método para implementar la paginación, pero para los programas de una sola página, la primera implementación también tiene sus beneficios. Para cantidades de datos no muy grandes, se puede usar el primer método de implementación, porque de esta manera, la carga de datos posterior será muy suave. Así que aquí presentaremos estos dos métodos de implementación por separado.
2.1 Implementación de la carga de datos parciales cada vez
El código de backend aquí usa el código del artículo anterior, pero agrega algunos datos de ejemplo. El código de implementación de backend específico es:
/// <summary> /// Servicio de API web, proporcionando servicios de datos para el front-end web /// </summary> public class TaskController: apicOntroller {private readonly taskRepository _TaskRepository = taskRepository.current; public IEnumerable <ark> getAll () {return _TaskRepository.getall (). Orderby (a => a.id); } [Route ("API/Tark/GetByPaged")] public PagedModel getAll ([fromuri] int pageIndex) {const int pageSize = 3; int tareas var = _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}; // devuelve datos return Pagedata; }} //// <summary> /// repositorio de tareas, encapsulando todas las operaciones sobre la base de datos /// </summary> public class TaskRepository {#region static archivado static static lazy <taskRepository> _TaskRepository = new Lazy <taskrepository> (() => taskRepository ()); public static taskRepository Current {get {return _TaskRepository.Value; }} #EnDregion #region Fields Private Readonly List <Kark> _Tasks = New List <Kark> () {New Task {id = 1, name = "Crear un programa SPA", Descripción = "SpA (aplicación web de una sola página), la ventaja de SPA es una pequeña cantidad de altura de banda y una experiencia suave", "Aprendizaje de aprendizaje duro", Tiempo de finalización = Datetime.parse (datetime.now.adddays (1) .ToString (culturaInfo.invariantCulture))}, nueva tarea {id = 2, name = "Learning Knockoutjs", Descripción = "KnockoutJS es una biblioteca de clase MVVM que admite la unión de dos vías", propietario = "Tommy Li", Finishtime = Datetime.parse (datetime.now.adddays (2) .ToString (culturinfo.invariantCulture))}, nueva tarea {id = 3, name = "Learn AngularJS", Descripción = "AngularJS es un marco MVVVM que integra MVVM y MVC con uno.", Propietaria = "Li Zhi", Tiempo de finalización = Datetime.parse (dateTime.Now.adddays (3) .ToString (culturinfo.invariantCulture))}, nueva tarea {id = 4, name = "Learn asp.net MVC Sitio web", descripción = "Glimpse es una herramienta de prueba de rendimiento en .NET, que admite ASP.NET, ASP.NET MVC, EF, etc. La ventaja es que la ventaja es la ventaja de Modify. proyecto, y puede generar el tiempo de ejecución de cada enlace de la ejecución del código ", propietario =" tonny li ", finktime = dateTime.Parse (datetime.now.adddays (4) .ToString (culturainfo.invariantCulture))}, nueva tarea {id = 5, nombre =" Tarea de prueba 1 ", Descripción =" Tarea de prueba 1 ", propietario =" li zhi ",", ",", ", finalización de la actualidad = = Datetime.parse (datetime.now.adddays (5) .ToString (culturinfo.invariantCulture))}, nueva tarea {id = 6, nombre = "Tarea de prueba 2", descripción = "Tarea de prueba 2", propietario = "Li Zhi", FinalTime = Datetime.parse (datetime.now.adddays (6) .ToString (culturinfo.invariantCulture))}, nueva tarea {id = 7, name = "Tarea de prueba 3", descripción = "Tarea de prueba 3", propietario = "li zhi", finktime = DateTime.Parse (DateTime.Now.Adddays (7) .ToString (CultureInfo.InvariantCulture))},}; #EnDregion #region Métodos públicos public IEnumerable <ark> getAll () {return _Tasks; } public IEnumerable <ark> getAll (int pagenumber, int pageSize, out int totalCount) {var skip = (pageNumber - 1) * pageSize; var Take = PageSize; TotalCount = _Tasks.Count; return _tasks.skip (omitir) .take (tomar); } Tarea pública get (int id) {return _tasks.find (p => p.id == id); } public tarea add (elemento de tarea) {if (item == NULL) {tire nuevo argumentoNulLException ("item"); } item.id = _tasks.count + 1; _tasks.Add (ítem); artículo de devolución; } public void remove (int id) {_tasks.removeall (p => p.id == id); } Update public bool (elemento de tarea) {if (item == null) {lanzar nueva argumentoNulLException ("item"); } var taskItem = get (item.id); if (taskItem == null) {return false; } _tasks.remove (taskItem); _tasks.Add (ítem); devolver verdadero; } #Endregion}Código de implementación de front-end web:
@{Verbag.title = "index2"; diseño = "~/vistas/compartir/_layout.cshtml";} <div id = "list2"> <h2> El segundo método de implementación de la lista de la pagination-task </h2> <div> <table> <thead> <tr> <th> numer charge</th><th>creation time</th><th>complete time</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><td data-bind="text: Descripción "> </td> <td data-bind =" text: propietario "> </td> <td data-bind =" text: creationtime "> </td> <td data-bind =" text: finkemtime "> </td> <td data-bind =" text: state "> </td> </tr> </tbody> colsspan = "8"> <img src = "/images/loading.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot: loadingstate"> <tr> <td colsspan = "8"> <div> hay un total de <span data-bind = "text: totalcunt"> <////la especie de presa> y cada vital data-bind = "text: pageSize"> </span> registros </div> <div> <ul> <li data-bind = "css: {discapedied: pageIndex () ==== 1}"> <a href = "#" data-bind = "haga clic: anterior"> «</a> </li> </ul> <ul Data-bind =" forach: Allpages "> <li dataSs:" csss: "csss:" csss: "csss:" csss: ":" csss: "csss:" css: "css:" csss: "csss:" csss: "csss:" csss: ":" $ data.pageNumber === ($ root.pageIndex ())} "> <a href ="#"data-bind =" text: $ data.pageNumber, click: function () {$ root.gotopage ($ data.pageNumber); PageCount} "> <a href ="#"data-bind =" haga clic: Next ">» </a> </li> </ul> </div> </div> </td> </tfoot> </table> </div> </div>La implementación JS correspondiente es:
// La segunda forma de implementar la paginación var listViewModel2 = function () {// ViewModel en sí. Se utiliza para evitar la confusión de alcance al usar esto directamente var self = this; self.loadingstate = ko.observable (true); self.pagesize = ko.observable (3); // data this.pagedList = ko.observableArray (); // El número de página a acceder a este.pageIndex = ko.observable (1); // número total de páginas this.pageCount = ko.observable (1); // el número de páginas this.allpages = = ko.observableArray (); // La página actual this.CurrenGePage = ko.observable (1); self.totalCount = ko.observable (1); this.Refresh = function () {// restringir el número de solicitud de solicitud dentro del número de página de datos if (self.pageIndex () <1) self.pageIndex (1); if (self.pageIndex ()> self.pageCount ()) {self.pageIndex (self.pageN SendAJAxRequest ("get", function (data) {// Antes de cargar nuevos datos, eliminar los datos originales self.pagedList.removeall (); self.allpages.removeall (); self.totalCount (data.totalCount); self.pagePount (data.pageCount); self.loadingstate (false); Var i = 1; ISHEPAGED (dataCount (data.pagount); self.loadingState (false); for (var i = 1; miot. i ++) {// Número de página Recargente Self.Alspages.push ({PageNumber: I});} // para ... En la declaración se usa para colocar las propiedades de una matriz o objeto para ... en ... en cada vez que el código en el bucle se ejecuta en los elementos de la matriz u objeto. self.pagedList.push (data.pagedData [i]);}}, 'getByPaged', {'pageIndex': self.pageIndex ()});}; // Solicitar la primera página de datos this.first = function () {self.pageIndex (1); self.Refresh ();}; // solicitar la próxima página de datos este. {self.pageIndex (this.pageIndex () + 1); self.refresh ();}; // Solicite la página de datos anterior this.previous = function () {self.pageIndex (this.pageIndex () - 1); self.refresh ();}; // solicita la última página de datos this.last = function () {self.pageIndex (this.pagageDex () 1); self.refresh ();}; // redirigir a una determinada página this.gotopage = function (data, event) {self.pageIndex (data); self.refresh ();};};}; función sendAraJaxRequest (httpmethod, llamadas, url, reqData) {$ .AJAX ("/api/tarea" + (url? "/" + url: "), {type: httpmethod, suctar: callback, data: reqData});} $ (documento) .ader (function () {var viewModel ListViewModel2 (); ViewModel.Refresh (); if ($ ('#list2'). Longitud) ko.applyBindings (ViewModel, $ ('#list2'). Get (0));});Aquí hay una introducción a la idea de implementación de usar knockoutjs para implementar la función de paginación:
1. Después de cargar la página, inicie una solicitud AJAX para llamar al servicio REST de manera asincrónica para solicitar parte de los datos.
2. Luego muestre los datos solicitados a través de la vinculación de KnockoutJS.
3. Vincule la información de paginación correspondiente a la paginación de bootstrap
4. Cuando el usuario haga clic para convertir la página, inicie una solicitud AJAX para llamar al servicio REST de forma asincrónica y mostrar los datos solicitados.
Esta es la relación lógica del código de llamada descrito anteriormente. Puede consultar el código JS correspondiente para comprender la descripción anterior. En este punto, se completa nuestro segundo método de implementación.
2.2 Cargue todos los datos por primera vez y luego muestre todos los datos.
A continuación, presentaremos el primer método de implementación. En este método de implementación, los usuarios solo sentirán que los datos se están cargando por primera vez, y no sentirán que la página se carga durante el proceso de giro de la página. Esto hará que los usuarios se sientan más suaves cuando no hay demasiados datos en algunos casos.
La idea de implementación específica es no mostrar todos los datos solicitados en la página, porque hay demasiados datos y se mostrarán en la página a la vez, y los usuarios pueden deslumbrarse. Mostrar la paginación de datos hará que los usuarios vieran más claro.
El código de implementación específico de JS front-end web es:
var listViewModel = function () {var self = this; window.viewModel = self; self.list = ko.observableArray (); self.pagesize = ko.observable (3); self.pageIndex = ko.observable (0); // el número de página a acceder a self.totalCount = ko.observable (1); // Número total de registros self.loadingState = ko.observable (true); self.pagedList = ko.dependentObServable (function () {var size = self.pageSize (); var start = self.pageIndex () * size; return self.list.slice (inicio, inicio + size);}); self.maxpageIndex = ko.dependentObServable (function () {return Math.ceil (self.list (). longitude. 1;}); self.previousPage = function = function () {if (self.pageIndex ()> 0) {self.pageIndex (self.PageIndex () - - 1);}}; self.NextPage = function () {if (self.pageStex () <SeleSeSeSeSmaxPageIndex () 1);} ial {self.pageIndex (index);};}; var listViewModel = new ListViewNel (); function bindViewModel () {sendAraJaxRequest ("get", function (data) {ListViewModel.LoadingState (false); ListViewModel.list (data); ListViewModel.totalCount (data.l longitud; ($ ('##list'). longitud) ko.applybindings (listViewModel, $ ('#list'). get (0));}, null, null);} $ (documento) .ready (function () {bindViewModel ();});La implementación de su página de front-end es similar a la implementación anterior. El código de página específico es el siguiente:
@{ViewBag.title = "index"; LEsout = "~/Views/Shared/_Layout.cshtml";} <div id = "List"> <h2> Lista de tareas </h2> <iv> <Table> <Thead> Tiempo </th> <th> Tiempo de finalización </th> <th> Statu </th> </tr> </tbody data-bind = "foreach: PagedList"> <tr> <td data-bind = "text: id"> </td> <td> <a data-bind = "text: nombre"> </a> </td> <td data-bind = "text: descripción"> </td <td <td " data-bind = "text: propietario"> </td> <td data-bind = "text: creationtime"> </td> <td data-bind = "text: finkTime"> </td> <td data-bind = "text: state"> </td> </tr> </tbody> <tbody-bind = "if: cargarstate"> <tr> src = "/images/loading.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot: loadingstate"> <tr> <td colspan = "8"> <div> <div> hay un total de <span data-bind = "text: totalcount"> </span> registros, y cada página se muestra: <span data bind "bind" PageSize "> </span> registros </div> <div> <ul> <li data-bind =" css: {discapacition: pageIndex () === 0} "> <a href ="#"data-bind =" haga clic: anteriorPage ">« </a> </li> </ul> <ul data-bind = "foreach: allpages"> <li data-bind = "csss: {{{ul> $ data.pageNumber === ($ root.pageIndex () + 1)} "> <a href ="#"data-bind =" text: $ data.pageNumber, click: function () {$ root.moveTopage ($ data.pageNumber-1); === maxPageIndex ()} "> <a href ="#"data-bind =" haga clic: nextPage ">» </a> </li> </ul> </div> </div> </td> </tr> </tfoot> </table> </viv> </div> </iv>3. Efecto de operación
A continuación, echemos un vistazo al efecto de paginación implementado usando knockoutjs:
4. Resumen
En este punto, el contenido que se presentará en este artículo ha terminado. Aunque el contenido implementado en este artículo es relativamente simple, para algunos amigos que son nuevos en KnockoutJs, creo que la implementación de este artículo será una gran orientación. A continuación, compartiré con ustedes el contenido relevante de AngularJS.
Lo anterior es una explicación detallada de los ejemplos de combinación de Bootstrap con knockoutjs para lograr efectos de paginación que el editor le presentó. ¡Espero que te sea útil!