KnockoutJS adalah kerangka kerja MVVM yang diimplementasikan JavaScript. Sangat bagus. Misalnya, setelah menambahkan atau mengurangi item data daftar, tidak perlu menyegarkan seluruh fragmen kontrol atau menulis penambahan JS dan node penghapusan sendiri. Tentukan saja templat dan atribut yang memenuhi definisi sintaksnya. Sederhananya, kita hanya perlu memperhatikan akses ke data.
1. Pendahuluan
Karena sistem perusahaan perlu diubah baru-baru ini, saya berencana untuk menggunakan KnockoutJs untuk membuat front-end web untuk sistem baru yang dirubah. Selama proses tersebut, saya mengalami masalah - cara menggunakan KnockoutJs untuk menyelesaikan fungsi pagination. Dalam artikel sebelumnya, KnockoutJs tidak diperkenalkan untuk mengimplementasikan pagination, jadi dalam artikel ini, bootstrap KnockoutJS + akan digunakan untuk mengimplementasikan tampilan data pagination.
2. Gunakan KnockoutJs untuk mengimplementasikan pagination
Ada dua cara untuk mengimplementasikan paging. Yang pertama adalah memuat semua data dan kemudian menampilkan semua data pada halaman; Yang kedua adalah memuat hanya sebagian data setiap kali, dan memuat kembali data berikutnya setiap saat.
Untuk dua metode ini, pagination diimplementasikan menggunakan metode Razor umumnya mengadopsi metode kedua untuk mengimplementasikan pagination, tetapi untuk program satu halaman, implementasi pertama juga memiliki manfaatnya. Untuk jumlah data yang tidak terlalu besar, metode implementasi pertama dapat digunakan, karena dengan cara ini, pemuatan data berikutnya akan sangat lancar. Jadi di sini kami akan memperkenalkan dua metode implementasi ini secara terpisah.
2.1 Implementasi pemuatan data parsial setiap kali
Kode backend di sini menggunakan kode dari artikel sebelumnya, tetapi menambahkan beberapa contoh data. Kode implementasi backend spesifik adalah:
/// <summary> /// layanan API web, menyediakan layanan data untuk front-end web /// </summary> kelas publik TaskController: Apicontroller {private readonly TaskRepository _TaskRepository = TaskRepository.current; public iEnumerable <ceck> getAll () {return _taskRepository.getAll (). orderby (a => a.id); } [Rute ("API/Tugas/GetBypaged")] PagedModel Publik GetAll ([fromuri] int pageIndex) {const int pageSize = 3; int totalcount; var tugas = _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}; // pengembalian data pengembalian data pagedata; } }/// <summary> /// Task Repository, encapsulating all operations about the database /// </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 bidang Private Readonly List <Keck> _tasks = Daftar baru <Keck> () {Tugas baru {id = 1, name = "Buat program spa", deskripsi = "spa (aplikasi web single), finish daku, finish, spa adalah sejumlah kecil bandwidth dan pengalaman lancar", pemilik = "finishtime", finish time = Datetime.parse (DateTime.now.Adddays (1) .toString (cultureInfo.invariantCulture)))}, tugas baru {id = 2, name = "Learning Knockoutjs", description = "Knockoutjs adalah perpustakaan kelas MVVM yang mendukung pengikat dua arah", pemilik = "TOMMY Li. Datetime.parse (datetime.now.adddays (2) .toString (cultureInfo.invariantCulture)))}, tugas baru {id = 3, name = "pelajari angularjs", description = "AngularJS adalah kerangka MVVM yang mengintegrasikan MVVM dan MVC dengan satu." Datetime.parse (datetime.now.adddays (3) .toString (cultureInfo.invariantCulture))}, tugas baru {id = 4, name = "pelajari situs web asp.net mvc tidak ada. 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 (cultureInfo.invariantculture))}, tugas baru {id = 6, name = "Tes Tugas 2", description = "Tes Tugas 2", pemilik = "li zhi", finishtime = Datetime.parse (datetime.now.adddays (6) .toString (cultureInfo.invariantculture))}, tugas baru {id = 7, name = "Tes Tugas 3", deskripsi = "Tes Tugas 3", pemilik = "li zhi", finishtime = Datetime.parse (datetime.now.adddays (7) .toString (cultureInfo.invariantCulture))},}; #endregion #Region Metode publik IEnumerable PUBLIK <Keck> getAll () {return _tasks; } public iEnumerable <Keck> getAll (int pagenumber, int pageSize, out int totalCount) {var skip = (pagenumber - 1) * halaman; var take = pageSize; TotalCount = _tasks.count; return _tasks.skip (lewati) .take (ambil); } tugas publik get (int id) {return _tasks.find (p => p.id == id); } Tugas Publik Tambah (item tugas) {if (item == null) {lempar argumentNullexception baru ("item"); } item.id = _tasks.count + 1; _tasks.add (item); item pengembalian; } public void Remove (int id) {_tasks.removeall (p => p.id == id); } pembaruan bool publik (item tugas) {if (item == null) {throw new ArgumentNullexception ("item"); } var taskitem = get (item.id); if (taskitem == null) {return false; } _tasks.remove (taskitem); _tasks.add (item); Kembali Benar; } #endregion}Kode Implementasi Front-End Web:
@{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 Tagihan </t> <th> Waktu Penciptaan </th> <th> Lengkapi Waktu </th> <TH> Status </tr> </tr> </lest> <tbody data-bind = "foreach: pagedlist"> <tr> <td-bind = "Text: id"> </td> <td> <td> <td- data-bind = "TEXT"> </td> <td> <td> <td> <td> <td- data-bind = "name"> </td> </td> <td> <td> <a data-bind = "name"> Deskripsi "> </td> <td data-bind =" Teks: pemilik "> </td> <td data-bind =" text: creationTime "> </td> <td data-bind =" Teks: finishtime "> </td> <td-bind =" state "> </td> </tr> </tbody> <t-body =" TEKP: state "> </td> </tr> </tbody> <t-body =" ife: "if: TD: TEBBIND =" TEB-BOBY = " colspan="8"><img src="/images/loading.gif" /></td></tr></tbody><tfoot data-bind="ifnot:loadingState"><tr><td colspan="8"><div><div>There are a total of <span data-bind="text: totalCount"></span> records, and each page is displayed: <span Data-bind = "Teks: Halaman"> </span> catatan </div> <div> <ul> <li data-bind = "css: {dinonaktifkan: pageIndex () === 1}"> <a href = "#" data-bind = "klik: sebelumnya"> </a> </li> </ul> <uL-bind = "Klik: sebelumnya"> </a> </li> </ul> <uL-bind = "FORM: ALLAGES" </a> </li> </ul> </Ul> </Ul Bind = "FORM: ALLAGES"> </a> </li> </ul> <uL-bind = " Aktif: $ data.pagenumber === ($ root.pageIndex ())} "> <a href ="#"data-bind =" Teks: $ data.pagenumber, klik: fungsi () {$ root.gotopage ($ data.pagenumber); === PAGECOUNT} "> <a href ="#"data-bind =" klik: next ">» </a> </li> </ul> </div> </div> </td> </tfoot> </able> </div> </div>Implementasi JS yang sesuai adalah:
// Cara kedua untuk mengimplementasikan paging var listViewModel2 = function () {// viewModel itu sendiri. Digunakan untuk mencegah kebingungan lingkup saat menggunakan ini secara langsung var self = ini; self.loadingState = ko.observable (true); self.pagesize = ko.observable (3); // data this.pagedlist = ko.observableArray (); // nomor halaman yang akan diakses ini. ko.observableArray (); // halaman ini this.currensrepage = ko.observable (1); self.totalCount = ko.observable(1);this.refresh = function() {//Restrict the request page number within the data page number if (self.pageIndex() < 1)self.pageIndex(1);if (self.pageIndex() > self.pageCount()) {self.pageIndex(self.pageCount());}//Post asynchronously load data sendajaxRequest ("get", function (data) {// Sebelum memuat data baru, hapus data asli self.pagedlist.removeall (); self.allpages.removeall (); mandiri. i ++) {// Muat ulang nomor halaman mandiri self.pagedlist.push (data.pagedData [i]);}}, 'getBypaged', {'pageIndex': self.pageIndex ()});}; // Minta halaman pertama data ini. {self.pageIndex (this.pageIndex () + 1); self.refresh ();}; // Minta halaman data sebelumnya this.previous = function () {self.pageIndex (this.pageIndex () - 1); selfresh ();}; // minta halaman terakhir ini. 1); self.refresh ();}; // Redirect ke halaman tertentu this.gotopage = function (data, peristiwa) {self.pageIndex (data); self.refresh ();};};}; fungsi sendajaxRequest (httpmethod, callback, url, reqdata) {$ .Ajax ("/API/Tugas" + (url? "/" + url: ""), {type: httpmethod, Success: callback, data: reqdata});} $ (dokumen). ListViewModel2 (); viewmodel.refresh (); if ($ ('#list2'). Panjang) ko.ApplyBindings (viewModel, $ ('#list2'). Get (0));});Berikut adalah pengantar ide implementasi menggunakan KnockoutJs untuk mengimplementasikan fungsi pagination:
1. Setelah halaman dimuat, inisiasi permintaan AJAX untuk menghubungi layanan REST secara tidak sinkron untuk meminta sebagian data.
2. Kemudian tampilkan data yang diminta melalui pengikatan KnockoutJs.
3. Bind Informasi paging yang sesuai dengan paging bootstrap
4. Ketika pengguna mengklik untuk membalik halaman, memulai permintaan AJAX untuk menghubungi layanan REST secara tidak sinkron dan menampilkan data yang diminta.
Ini adalah hubungan logis dari kode panggilan yang dijelaskan di atas. Anda dapat merujuk pada kode JS yang sesuai untuk memahami deskripsi di atas. Pada titik ini, metode implementasi kedua kami selesai.
2.2 Muat semua data untuk pertama kalinya, dan kemudian menampilkan semua paging data
Selanjutnya, kami akan memperkenalkan metode implementasi pertama. Dalam metode implementasi ini, pengguna hanya akan merasa bahwa data dimuat untuk pertama kalinya, dan mereka tidak akan merasakan pemuatan halaman selama proses belok halaman. Ini akan membuat pengguna merasa lebih halus ketika tidak ada terlalu banyak data dalam beberapa kasus.
Gagasan implementasi spesifik adalah untuk tidak menampilkan semua data yang diminta pada halaman, karena ada terlalu banyak data dan akan ditampilkan pada halaman sekaligus, dan pengguna mungkin terpesona. Menampilkan paging data akan membuat pengguna melihat lebih jelas.
Kode implementasi spesifik JS front-end web adalah:
var listViewModel = function () {var self = this; window.viewModel = self; self.list = ko.observableArray (); self.pagesize = ko.observable (3); self.pageIndex = ko.observable (0); // Nomor halaman yang akan diakses self.totalcount = ko.observable (1); // Jumlah total catatan 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. 1;}); self.previouspage = function () {if (self.pageIndex ()> 0) {self.pageIndex (self.pageIndex () - 1);}}; self.nextpage = function () {if (selfselds self.maxpageDex () {if.pageIndex (mandel. 1);}}; self.allpages = ko.DependentObservable (function () {var halaman = []; untuk (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 (listView); ($ ('#list'). Length) ko.ApplyBindings (listViewModel, $ ('#list'). get (0));}, null, null);} $ (dokumen) .ready (function () {bindViewModel ();});Implementasi halaman front-endnya mirip dengan implementasi sebelumnya. Kode halaman tertentu adalah sebagai berikut:
@{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 Waktu </t> <t th> Waktu Penyelesaian </th> <TH> statu </tr> </tr> </tbody data-bind = "foreach: pagedlist"> <tr> <td-bind = "Teks: id"> </td> <td> <a data = "TEKS: nama" nama "> </a> </td> <td> <a td =" TEXT: NAME "> </a> </td> <td> <a td =" TEXT "TEKS" Data-bind = "Teks: pemilik"> </td> <td data-bind = "Teks: CreationTime"> </td> <td data-bind = "Teks: finishtime"> </td> <td data-bind = "Teks: state"> </td> </tr> </tbody> <tbody data-bind = "if: if: if: loadState =" </tbody> <tbody> <tbody data-bind = "if: if: loadsate =" "" "" "if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: if: src = "/gambar/loading.gif"/> </td> </tr> </tbody> <tfoot data-bind = "ifnot: LoadingState"> <tr> <td colspan = "8"> <div> <Div> Ada total <span data-bind = "Text: TOXTCOUNT"> </SPAN> CATATAN, dan setiap CATATAN: SPAN DATA-BIND = "TEXT: TEXTCOUNT"> </span> Halaman "> </span> catatan </div> <div> <ul> <li data-bind =" css: {dinonaktifkan: pageIndex () === 0} "> <a href ="#"data-bind =" klik: priorpage ">« </a> </li> </ul> <ul bind = "foreach: foreach:« </a> </li> </ul> <ul data-bind = "foreach: foreach:« </a> </li> </ul> <ul data-bind = "foreach: freach:« </a> </li> </ul> <ul data-bind = "foreach: foreach:« a. " $ data.pagenumber === ($ root.pageIndex () + 1)} "> <a href ="#"data-bind =" teks: $ data.pagenumber, klik: fungsi () {$ root.movetopage ($ data.pagenumber-1); === MAXPageIndex ()} "> <a href ="#"data-bind =" klik: nextpage ">» </a> </li> </ul> </div> </div> </td> </tr> </tfoot> </boable> </tiv> </div>3. Efek Operasi
Selanjutnya, mari kita lihat efek pagination yang diimplementasikan menggunakan KnockoutJs:
4. Ringkasan
Pada titik ini, konten yang akan diperkenalkan dalam artikel ini sudah berakhir. Meskipun konten yang diimplementasikan dalam artikel ini relatif sederhana, untuk beberapa teman yang baru mengenal KnockoutJ, saya percaya bahwa implementasi artikel ini akan menjadi banyak panduan. Selanjutnya, saya akan membagikan kepada Anda konten yang relevan dari AngularJS.
Di atas adalah penjelasan terperinci tentang contoh -contoh menggabungkan bootstrap dengan knockoutjs untuk mencapai efek pagination yang diperkenalkan editor kepada Anda. Saya harap ini akan membantu Anda!