Knockoutjs é uma estrutura MVVM implementada por JavaScript. Muito bom. Por exemplo, depois de adicionar ou diminuir os itens de dados da lista, não há necessidade de atualizar todo o fragmento de controle ou escrever nós de adição e exclusão de JS por você mesmo. Basta definir o modelo e os atributos que atendem às suas definições de sintaxe. Simplificando, precisamos apenas prestar atenção ao acesso aos dados.
1. Introdução
Como o sistema da empresa precisa ser renovado recentemente, pretendo usar knockoutjs para criar um front-end da Web para o novo sistema renovado. Durante o processo, encontrei um problema - como usar knockoutjs para concluir a função de paginação. No artigo anterior, o KnockoutJS não é introduzido para implementar a paginação; portanto, neste artigo, o KnockoutJs + Bootstrap será usado para implementar a exibição de dados de paginação.
2. Use knockoutjs para implementar a paginação
Existem duas maneiras de implementar a paginação. O primeiro é carregar todos os dados e depois exibir todos os dados nas páginas; O segundo é carregar apenas parte dos dados a cada vez e recarregar os dados subsequentes todas as vezes.
Para esses dois métodos, a paginação implementada usando o método Razor geralmente adota o segundo método para implementar a paginação, mas para programas de página única, a primeira implementação também tem seus benefícios. Para quantidades não muito grandes de dados, o primeiro método de implementação pode ser usado, porque, dessa maneira, o carregamento de dados subsequente será muito suave. Então, aqui vamos introduzir esses dois métodos de implementação separadamente.
2.1 Implementação do carregamento de dados parciais a cada vez
O código de back -end aqui usa o código do artigo anterior, mas adiciona alguns dados de exemplo. O código de implementação de back -end específico é:
/// <summary> /// Serviço de API da Web, fornecendo serviços de dados para o front-end da web /// </summary> classe pública TaskController: Apicontroller {Private readonly TaskRepository _TaskRepository = TaskRepository.Current; public ienumerable <kky> 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) .ordeby (a => aiod); var Pagedata = new PagedModel () {PageIndex = PageIndex, PagedData = Tasks.Tolist (), TotalCount = TotalCount, PageCount = (TotalCount+ Pagesize -1) / Pagesize}; // retorna os dados retornam Pagedata; }} /// <summary> /// repositório de tarefas, encapsulando todas as operações sobre o banco de dados /// </summary> classe pública TaskRepository {#Region Static Private Static LAZY <TaskRepository> _Taskrepository = new Lazy <) Taskrepositório (() => Newprepos public static TaskRepository Current {get {return _TaskRepository.Value; }} #ENDRegion #Region Campos List Private ReadOnly <Task> _Tasks = new List <Task> () {nova tarefa {id = 1, name = "Crie um programa de spa", Descrição = "Spa (Aplicativo da Web de uma única página), a vantagem do SPA é uma pequena quantidade de largura de banda e uma experiência suave", "," aprendizagem ",", dura ", Finalmente", Finalize é uma pequena quantidade de largura de banda e uma experiência suave ",", "aprendizado DateTime.Parse (DateTime.now.adddays (1) .toString (culturaInfo.inVariantCulture))}, nova tarefa {id = 2, name = "Aprendendo knockoutjs", description = "Knockoutjs é uma MVVM Class Library que suporta bidirecionais", proprietário = "" DateTime.Parse (DateTime.now.adddays (2) .tostring (culturaInfo.invariantculture))}, nova tarefa {id = 3, name = "Learn Angularjs", description = "Angularjs é uma estrutura MVVM que integra MVV e MVC com um." DateTime.Parse (DateTime.now.adddays (3) .tostring (culturaInfo.inVariantculture))}, nova tarefa {id = 4, name = "Learn asp.net MVC Site", como o que não é um teste de desempenho, como o que não é o site de que não é o que não é um teste, como o site de que não é o que não é um teste de desempenho, como o que não é um teste de desempenho, que não é um teste, que não é um que precisa de uma ferramenta de performance. code of the original project, and can output the execution time of each link of the code execution", Owner = "Tonny Li", FinishTime = DateTime.Parse(DateTime.Now.AddDays(4).ToString(CultureInfo.InvariantCulture)) }, new Task { Id =5, Name = "Test Task 1", Description = "Test Task 1", Owner = "Li Zhi", FinishTime = DateTime.Parse (DateTime.now.adddays (5) .toString (culturaInfo.inVariantculture))}, nova tarefa {id = 6, name = "Task 2", Descrição = "Tarefa de teste 2", proprietário = "li zhi", tempo de chegada = DateTime.Parse (DateTime.now.adddays (6) .toString (CultureInfo.inVariantCulture))}, nova tarefa {id = 7, nome = "Tarefa de teste 3", Descrição = "Tarefa de teste 3", proprietário = "li zhi", tempo de chegada = DateTime.Parse (DateTime.now.adddays (7) .toString (CultureInfo.inVariantculture))},}; #endregion #region público métodos public ienumerable <kky> getAll () {return _Tasks; } public ienumerable <kky> 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); } tarefa pública get (int id) {return _tasks.find (p => p.id == id); } public tarefa add (item de tarefa) {if (item == null) {tiro novo argumentnullexception ("item"); } item.id = _tasks.count + 1; _Tasks.add (item); item de retorno; } public void remover (int id) {_tasks.removeall (p => p.id == id); } public bool update (item de tarefa) {if (item == null) {lança novo argumentnulLexception ("item"); } var taskItem = get (item.id); if (taskItem == null) {return false; } _tasks.remove (taskItem); _Tasks.add (item); retornar true; } #endregion}Código de implementação front-end da Web:
@{Viewbag.title = "index2"; layout = "~/views/shared/_layout.cshtml";} <div id = "list2"> <h2> O segundo método de implementação da lista de paginação </mos </h2> <div> <table> <thead> <tr> <th> <hh> Charge </th> <th> Tempo de criação </th> <th> Tempo completo </th> <th> status </th> </tr> </tratd> <tbody data-bind = "foreach: PagedList"> <tr> <td data-bind = "text: id"> </td> <td> <a data-bind = "text:" Nome "> Descrição "> </td> <td data-bind =" text: proprietário "> </td> <td data-bind =" text: criação time "> </td> <td data-bind =" text: time time "> </td> <td data-bind =" text: "> </td> </tr> </tbody> <tbody-bmbody-bind =" text: "> </td> </tr> </tbody <tbody-bbody-bind =" text: "> </td> </tr> </tdbody-Tbody-bind =" colspan = "8"> <img src = "/imagens/carregamento.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot: carregingstate"> <tr> <td colspan = "8"> <div> existe um total de <e spran-bind = " Data-bind = "Texto: Pagesize"> </span> Registros </div> <div> <ul> <li data-bind = "css: {desabilled: PageIndex () === 1}"> <a href = "#" data-bind = "clique: anterior"> «</a> </li> </ul> <ul> $ data.pageNumber === ($ root.pageIndex ())} "> <a href ="#"data-bind =" text: $ data.pagenumber, clique: function () {$ root.gotopage ($ data.pagenumber); pageCount} "> <a href ="#"data-bind =" clique: a seguir ">» </a> </li> </ul> </div> </div> </td> </tfoot> </table> </div> </div>A implementação JS correspondente é:
// A segunda maneira de implementar a paginação var listViewModel2 = function () {// em si viewModel. Usado para evitar a confusão do escopo ao usar isso diretamente var self = this; self.loadingingState = ko.observable (true); self.Pagesize = ko.observable (3); // dados this.pagagedList = ko.observablearray (); // o número da página a ser acessado isso.PageIndex = Ko.Observable (1); // Número total de páginas isto. ko.observableArray (); // a página atual this.currengePage = ko.observable (1); Self.TotalCount = Ko.observable (1); this.Refresh = function () {// restringe o número da página de solicitação dentro do número da página de dados se (self.pageIndex () <1) self.pageIndEx (1); se (self.pageIndEx ()> self.pagount ()) {.PageMex (SelfEnTex; sendajaxRequest ("get", function (dados) {// Antes de carregar novos dados, remova os dados originais. i ++) {// Recarregue o número da página Self.allPages.push ({pagenumber: i});} // para ... na instrução é usada para fazer loop das propriedades de uma matriz ou objeto. self.pagedList.push (data.pageddata [i]);}}, 'getBypaged', {'PageIndex': self.pageIndex ()});}; // solicitar a primeira página de dados this.first = function () {self.pageIndEx (1); e self.refresh; {self.pageIndex (this.pageIndex () + 1); self.Refresh ();}; // Solicite a página anterior dos dados this.previous = function () {self.pageIndEx (this.pageIndEx () - 1); Self.Refresh ();}; 1); self.Refresh ();}; // redireciona para uma determinada página this.gotopage = function (dados, evento) {self.pageIndex (data); self.Refresh ();};};}; função sendajaxRequest (httpmethod, retorno de chamada, url, reqdata) {$ .ajax ("/api/tarefa" + (url? "/" + url: ""), {type: httpmethod, sucess: success: retorno de chamada: reqdata}); ListViewModel2 (); ViewModel.Refresh (); if ($ ('#list2'). Length) Ko.ApplyBindings (ViewModel, $ ('#list2'). Get (0));});Aqui está uma introdução à idéia de implementação de usar knockoutjs para implementar a função de paginação:
1. Depois que a página for carregada, inicie uma solicitação AJAX para ligar para o serviço REST de forma assíncrona para solicitar parte dos dados.
2. Em seguida, exiba os dados solicitados através da ligação KnockoutJS.
3. Ligue as informações de paginação correspondentes à paginação de bootstrap
4. Quando o usuário clicar para girar a página, inicie uma solicitação AJAX para ligar para o Serviço RESTE de forma assíncrona e exibir os dados solicitados.
Esta é a relação lógica do código de chamada descrito acima. Você pode consultar o código JS correspondente para entender a descrição acima. Neste ponto, nosso segundo método de implementação é concluído.
2.2 Carregue todos os dados pela primeira vez e, em seguida, exiba todas as paginas de dados
Em seguida, apresentaremos o primeiro método de implementação. Nesse método de implementação, os usuários só sentirão que os dados estão carregando pela primeira vez e não sentirão o carregamento da página durante o processo de giro da página. Isso fará com que os usuários se sintam mais suaves quando não houver muitos dados em alguns casos.
A idéia de implementação específica é não exibir todos os dados solicitados na página, porque há muitos dados e serão exibidos na página de uma só vez, e os usuários podem ficar deslumbrados. A exibição da paginação de dados tornará os usuários mais claros.
O código de implementação específico do front-end JS da Web é:
var listViewModel = function () {var self = this; window.viewModel = self; self.list = ko.observableArray (); self.pagesize = ko.observable (3); self.pageIndex = ko.observable (0); // o número da página a ser acessado 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 (start, size + size);}); return.maxpageIndex = ko.dependendable (função () {); 1;}); self.previouspage = function () {if (self.pageIndex ()> 0) {self.pageIndex (self.pageIndex () - 1);}}; self.nextPage = function () {if (self.pageIndEx () <self.maxpageIndEx () {) {if (self.pageIndEx () <e self.maxpageSex () {) {if (self.pageIndEx () <) 1);}}; self.allPages = ko.dependentObservable (function () {var páginas = []; para (var i = 0; i <= self.maxpageIndex (); i ++) {Pages.push ({pagenumber: (i+1)});}) {Pages); {self.pageIndex (index);};}; var listViewModel = new ListViewModel (); function bindViewModel () {SendajaxRequest ("get", function (data) {listViewModel.ToLoadState (false); listViewModel.List (Data); ($ ('#list'). Length) ko.applybindings (listViewModel, $ ('#list'). get (0));}, null, null);} $ (document) .ready (function () {bindViewModel ();});A implementação de sua página front-end é semelhante à implementação anterior. O código de página específico é o seguinte:
@{Viewbag.title = "index"; layout = "~/views/shared/_layout.cshtml";} <div id = "list"> <h2> Lista de tarefas </h2> <div> <tástina> </the> </the> descrição </thhead> Tempo </th> <th> Tempo de conclusão </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> Data-bind = "Texto: Proprietário"> </td> <td data-bind = "text: criação tempo"> </td> <td data-bind = "text: time time"> </td> <td data-bind = "text: state"> </td> </tr> </tbody <tddd-bind = "se: carregamento"> src = "/imagens/carregamento.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot: carregandostate"> <tr> <td colspan = "8"> <div> <div> Há um total de <span-bind = "text: spalcount"> </" Pagesize "> </span> registros </div> <div> $ data.pagenumber === ($ root.pageIndex () + 1)} "> <a href ="#"data-bind =" text: $ data.pagenumber, clique: function () {$ root.movetopage ($ data.pagenumber-1); === maxpageIndex ()} "> <a href ="#"data-bind =" click: nextpage ">» </a> </li> </ul> </div> </div> </td> </tr> </tfOOT> </div> </tiv> </div>3. Efeito de operação
Em seguida, vamos dar uma olhada no efeito da paginação implementado usando knockoutjs:
4. Resumo
Neste ponto, o conteúdo a ser introduzido neste artigo acabou. Embora o conteúdo implementado neste artigo seja relativamente simples, para alguns amigos que são novos no KnockoutJs, acredito que a implementação deste artigo será muita orientação. Em seguida, compartilharei com você o conteúdo relevante do AngularJS.
O exposto acima é uma explicação detalhada dos exemplos de combinação de bootstrap com knockoutjs para obter efeitos de paginação que o editor apresentou a você. Espero que seja útil para você!