Rumah  >  Artikel  >  hujung hadapan web  >  Contoh terperinci untuk menggabungkan Bootstrap dan KnockoutJs untuk mencapai kemahiran effect_javascript paging

Contoh terperinci untuk menggabungkan Bootstrap dan KnockoutJs untuk mencapai kemahiran effect_javascript paging

WBOY
WBOYasal
2016-05-16 15:02:401926semak imbas

KnockoutJS ialah rangka kerja MVVM yang dilaksanakan dalam JavaScript. sangat sejuk. Sebagai contoh, selepas item data senarai ditambah atau dipadamkan, tidak perlu memuat semula keseluruhan serpihan kawalan atau menulis JS untuk menambah atau memadam nod sendiri Anda hanya perlu pra-takrif templat dan atribut yang mematuhi sintaksnya takrifan. Ringkasnya, kita hanya perlu fokus pada capaian data.

1

Memandangkan sistem syarikat perlu disemak baru-baru ini, saya bercadang untuk menggunakan KnockoutJs untuk menjadikan web front-end untuk sistem baharu. Dalam proses melakukannya, saya menghadapi masalah - cara menggunakan KnockoutJs untuk melengkapkan fungsi paging. Dalam artikel sebelumnya, kami tidak memperkenalkan penggunaan KnockoutJs untuk melaksanakan paging, jadi dalam artikel ini, kami akan menambah penggunaan KnockoutJs+Bootstrap untuk melaksanakan paparan paging data.


2. Gunakan KnockoutJs untuk melaksanakan paging

Terdapat dua cara untuk melaksanakan paging Yang pertama adalah untuk memuatkan semua data, dan kemudian memaparkan semua data dalam halaman; data.


Untuk kedua-dua kaedah ini, paging yang dilaksanakan menggunakan kaedah Razor secara amnya menggunakan kaedah kedua untuk melaksanakan paging Walau bagaimanapun, untuk program satu halaman, kaedah pelaksanaan pertama juga sesuai untuk jumlah yang tidak terlalu besar data. Kaedah pelaksanaan pertama boleh digunakan, kerana dalam kes ini, pengalaman pengguna pemuatan data berikutnya akan menjadi sangat lancar. Jadi kedua-dua kaedah pelaksanaan ini akan diperkenalkan di sini.


2.1 Pelaksanaan memuatkan data separa setiap kali

Kod bahagian belakang di sini menggunakan kod daripada artikel sebelumnya, dengan hanya beberapa data sampel tambahan ditambahkan. Kod pelaksanaan bahagian belakang khusus ialah:


/// <summary>
 /// Web API 服务,为Web前端提供数据服务
 /// </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([FromUri]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
   };
   //返回数据
   return pageData;
  }
 }
/// <summary>
 /// 任务仓储,封装了所有关于数据库的操作
 /// </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 Fields
  private readonly List<Task> _tasks = new List<Task>()
  {
   new Task
   {
    Id =1,
    Name = "创建一个SPA程序",
    Description = "SPA(single page web application),SPA的优势就是少量带宽,平滑体验",
    Owner = "Learning hard",
    FinishTime = DateTime.Parse(DateTime.Now.AddDays(1).ToString(CultureInfo.InvariantCulture))
   },
   new Task
   {
    Id =2,
    Name = "学习KnockoutJs",
    Description = "KnockoutJs是一个MVVM类库,支持双向绑定",
    Owner = "Tommy Li",
    FinishTime = DateTime.Parse(DateTime.Now.AddDays(2).ToString(CultureInfo.InvariantCulture))
   },
   new Task
   {
    Id =3,
    Name = "学习AngularJS",
    Description = "AngularJs是MVVM框架,集MVVM和MVC与一体。",
    Owner = "李志",
    FinishTime = DateTime.Parse(DateTime.Now.AddDays(3).ToString(CultureInfo.InvariantCulture))
   },
   new Task
   {
    Id =4,
    Name = "学习ASP.NET MVC网站",
    Description = "Glimpse是一款.NET下的性能测试工具,支持asp.net 、asp.net mvc, EF等等,优势在于,不需要修改原项目任何代码,且能输出代码执行各个环节的执行时间",
    Owner = "Tonny Li",
    FinishTime = DateTime.Parse(DateTime.Now.AddDays(4).ToString(CultureInfo.InvariantCulture))
   },
   new Task
   {
    Id =5,
    Name = "测试任务1",
    Description = "测试任务1",
    Owner = "李志",
    FinishTime = DateTime.Parse(DateTime.Now.AddDays(5).ToString(CultureInfo.InvariantCulture))
   },
   new Task
   {
    Id =6,
    Name = "测试任务2",
    Description = "测试任务2",
    Owner = "李志",
    FinishTime = DateTime.Parse(DateTime.Now.AddDays(6).ToString(CultureInfo.InvariantCulture))
   },
   new Task
   {
    Id =7,
    Name = "测试任务3",
    Description = "测试任务3",
    Owner = "李志",
    FinishTime = DateTime.Parse(DateTime.Now.AddDays(7).ToString(CultureInfo.InvariantCulture))
   },
  };
  #endregion
  #region Public Methods
  public 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(take);
  }
  public Task Get(int id)
  {
   return _tasks.Find(p => p.Id == id);
  }
  public Task Add(Task item)
  {
   if (item == null)
   {
    throw new ArgumentNullException("item");
   }
   item.Id = _tasks.Count + 1;
   _tasks.Add(item);
   return item;
  }
  public void Remove(int id)
  {
   _tasks.RemoveAll(p => p.Id == id);
  }
  public bool Update(Task item)
  {
   if (item == null)
   {
    throw new ArgumentNullException("item");
   }
   var taskItem = Get(item.Id);
   if (taskItem == null)
   {
    return false;
   }
   _tasks.Remove(taskItem);
   _tasks.Add(item);
   return true;
  }
  #endregion
 }
Kod pelaksanaan bahagian hadapan web:


@{
ViewBag.Title = "Index2";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="list2">
<h2>分页第二种实现方式——任务列表</h2>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>描述</th>
<th>负责人</th>
<th>创建时间</th>
<th>完成时间</th>
<th>状态</th>
</tr>
</thead>
<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"></td>
<td data-bind="text: owner"></td>
<td data-bind="text: creationTime"></td>
<td data-bind="text: finishTime"></td>
<td data-bind="text: state"></td>
</tr>
</tbody>
<tbody data-bind="if: loadingState">
<tr>
<td colspan="8" class="text-center">
<img width="60" src="/images/loading.gif" />
</td>
</tr>
</tbody>
<tfoot data-bind="ifnot:loadingState">
<tr>
<td colspan="8">
<div class="pull-right">
<div>总共有<span data-bind="text: totalCount"></span>条记录, 每页显示:<span data-bind="text: pageSize"></span>条</div>
<div>
<ul class="pagination">
<li data-bind="css: { disabled: pageIndex() === 1 }"><a href="#" data-bind="click: previous">&laquo;</a></li>
</ul>
<ul data-bind="foreach: allPages" class="pagination">
<li data-bind="css: { active: $data.pageNumber === ($root.pageIndex()) }"><a href="#" data-bind="text: $data.pageNumber, click: function() { $root.gotoPage($data.pageNumber); }"></a></li>
</ul>
<ul class="pagination"><li data-bind="css: { disabled: pageIndex() === pageCount }"><a href="#" data-bind="click: next">&raquo;</a></li></ul>
</div>
</div>
</td>
</tr>
</tfoot>
</table>
</div>
</div> 
Pelaksanaan Js yang sepadan ialah:


// 实现分页的第二种方式
var ListViewModel2 = function() {
//viewModel本身。用来防止直接使用this的时候作用域混乱
var self = this;
self.loadingState = ko.observable(true);
self.pageSize = ko.observable(3);
//数据
this.pagedList = ko.observableArray();
//要访问的页码
this.pageIndex = ko.observable(1);
//总页数
this.pageCount = ko.observable(1);
//页码数
this.allPages = ko.observableArray();
//当前页
this.currengePage = ko.observable(1);
self.totalCount = ko.observable(1);
this.refresh = function() {
//限制请求页码在该数据页码范围内
if (self.pageIndex() < 1)
self.pageIndex(1);
if (self.pageIndex() > self.pageCount()) {
self.pageIndex(self.pageCount());
}
//post异步加载数据
sendAjaxRequest("GET", function (data) {
// 加载新的数据前,先移除原先的数据
self.pagedList.removeAll();
self.allPages.removeAll();
self.totalCount(data.totalCount);
self.pageCount(data.pageCount);
self.loadingState(false);
for (var i = 1; i <= data.pageCount; i++) {
//装填页码
self.allPages.push({ pageNumber: i });
}
//for...in 语句用于对数组或者对象的属性进行循环操作。
//for ... in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作。
for (var i in data.pagedData) {
//装填数据
self.pagedList.push(data.pagedData[i]);
}
}, 'GetByPaged', { 'pageIndex': self.pageIndex() });
};
//请求第一页数据
this.first = function() {
self.pageIndex(1);
self.refresh();
};
//请求下一页数据
this.next = function() {
self.pageIndex(this.pageIndex() + 1);
self.refresh();
};
//请求先前一页数据
this.previous = function() {
self.pageIndex(this.pageIndex() - 1);
self.refresh();
};
//请求最后一页数据
this.last = function() {
self.pageIndex(this.pageCount() - 1);
self.refresh();
};
//跳转到某页
this.gotoPage = function (data, event) {
self.pageIndex(data);
self.refresh();
};
};
function sendAjaxRequest(httpMethod, callback, url, reqData) {
$.ajax("/api/task" + (url &#63; "/" + url : ""), {
type: httpMethod,
success: callback,
data: reqData
});
}
$(document).ready(function () {
var viewModel = new ListViewModel2();
viewModel.refresh();
if ($('#list2').length)
ko.applyBindings(viewModel, $('#list2').get(0));
}); 
Berikut ialah pengenalan kepada idea pelaksanaan menggunakan KnockoutJs untuk melaksanakan fungsi paging:

1. Selepas halaman dimuatkan, mulakan permintaan Ajax untuk memanggil perkhidmatan REST secara tidak segerak untuk meminta beberapa data.


2. Kemudian paparkan data yang diminta melalui pengikatan KnockoutJs.


3. Ikat maklumat paging yang sepadan dengan paging Bootstrap


4. Apabila pengguna mengklik untuk membuka halaman, mulakan permintaan Ajax untuk memanggil perkhidmatan Rehat secara tidak segerak untuk meminta data, dan kemudian memaparkan data yang diminta.


Di atas ialah hubungan logik panggilan bagi kod yang diterangkan di atas Anda boleh merujuk kepada kod JS yang sepadan untuk memahami penerangan di atas. Pada ketika ini kaedah pelaksanaan kedua kami telah selesai.


2.2 Muatkan semua data buat kali pertama, dan kemudian paparkan semua data dalam halaman

Seterusnya, kami memperkenalkan kaedah pelaksanaan pertama Dengan kaedah pelaksanaan ini, pengguna hanya akan merasakan bahawa data dimuatkan untuk kali pertama, dan tidak akan merasakan halaman dimuatkan semasa proses mengubah halaman , untuk sesetengah Apabila data itu sendiri tidak terlalu banyak, pengalaman pengguna lebih lancar.


Idea pelaksanaan khusus bukanlah untuk memaparkan semua data yang diminta pada halaman, kerana terdapat terlalu banyak data dan pengguna mungkin terpesona jika ia dipaparkan pada halaman sekaligus. Memaparkan data dalam halaman akan menjadikannya lebih jelas untuk pengguna.


Kod pelaksanaan khusus Js bahagian hadapan Web ialah:


var ListViewModel = function () {
var self = this;
window.viewModel = self;
self.list = ko.observableArray();
self.pageSize = ko.observable(3); 
self.pageIndex = ko.observable(0); //要访问的页码
self.totalCount = ko.observable(1); //总记录数
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.maxPageIndex()) {
self.pageIndex(self.pageIndex() + 1);
}
};
self.allPages = ko.dependentObservable(function () {
var pages = [];
for (var i = 0; i <= self.maxPageIndex() ; i++) {
pages.push({ pageNumber: (i + 1) });
}
return pages;
});
self.moveToPage = function (index) {
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').length)
ko.applyBindings(listViewModel, $('#list').get(0));
}, null, null);
}
$(document).ready(function () {
bindViewModel();
}); 
Pelaksanaan halaman muka hadapannya adalah serupa dengan pelaksanaan sebelumnya. Kod halaman khusus adalah seperti berikut:


@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="list">
<h2>任务列表</h2>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>描述</th>
<th>负责人</th>
<th>创建时间</th>
<th>完成时间</th>
<th>状态</th>
</tr>
</thead>
<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"></td>
<td data-bind="text: owner"></td>
<td data-bind="text: creationTime"></td>
<td data-bind="text: finishTime"></td>
<td data-bind="text: state"></td>
</tr>
</tbody>
<tbody data-bind="if:loadingState">
<tr>
<td colspan="8" class="text-center">
<img width="60" src="/images/loading.gif" />
</td>
</tr>
</tbody>
<tfoot data-bind="ifnot:loadingState">
<tr>
<td colspan="8">
<div class="pull-right">
<div>总共有<span data-bind="text: totalCount"></span>条记录, 每页显示:<span data-bind="text: pageSize"></span>条</div>
<div>
<ul class="pagination">
<li data-bind="css: { disabled: pageIndex() === 0 }"><a href="#" data-bind="click: previousPage">&laquo;</a></li>
</ul>
<ul data-bind="foreach: allPages" class="pagination">
<li data-bind="css: { active: $data.pageNumber === ($root.pageIndex() + 1) }"><a href="#" data-bind="text: $data.pageNumber, click: function() { $root.moveToPage($data.pageNumber-1); }"></a></li>
</ul>
<ul class="pagination"><li data-bind="css: { disabled: pageIndex() === maxPageIndex() }"><a href="#" data-bind="click: nextPage">&raquo;</a></li></ul>
</div>
</div>
</td>
</tr>
</tfoot>
</table>
</div>
</div> 

3. Kesan operasi

Seterusnya, mari kita lihat kesan paging yang dicapai menggunakan KnockoutJs:


4. Ringkasan

Pada ketika ini, kandungan yang akan diperkenalkan dalam artikel ini berakhir Walaupun kandungan yang dilaksanakan dalam artikel ini agak mudah, bagi sesetengah rakan yang baru mengenali KnockoutJs, saya percaya pelaksanaan artikel ini akan menjadi banyak panduan. . Seterusnya, saya akan berkongsi dengan anda kandungan AngularJs yang berkaitan.


Di atas adalah penjelasan terperinci tentang contoh menggabungkan Bootstrap dan KnockoutJs untuk mencapai kesan paging yang diperkenalkan oleh editor. Saya harap ia akan membantu semua orang!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn