前言
konckout.js本人也是剛剛接觸,也是初學,本文的目的是使用ko和asp.net mvc4 webapi來實現一個簡單增刪改查操作。Knockout是一個以數據模型(data model)為基礎的能夠幫助你創建富文本,響應顯示和編輯用戶界面的JavaScript類庫。任何時候如果你的UI需要自動更新(比如:更新依賴於用戶的行為或者外部數據源的改變),KO能夠很簡單的幫你實現並且很容易維護。其作用簡單來說就是聲明所需的數據作為一個JavaScript 模型對象(model object),然后將DOM 元素或者模板(templates)綁定到它上面。
創建mvc4+webapi+konckout.js的簡單應用程序
1、首先准備一個測試的數據庫,我這以我隨便創建的一個數據庫為例
表結構如下圖:

2、創建一個mvc程序,並在項目中添加一個以上表的ado.net實體數據模型
添加完成以后:

3、添加添加一個帶讀寫操作的EmployeeApiController webapi控制器和用來實現增刪改查的普通控制器EmployeeController
添加是注意選擇是帶讀寫操作的webapi控制器,選擇好數據模型及數據庫上下文,方面vs自動為我們生成讀寫操作。

添加完成后自動生成的完整代碼:
using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Net; using System.Net.Http; using System.Web; using System.Web.Http; using Knockout.Models; namespace Knockout.Controllers { public class EmployeeApiController : ApiController { private DemoDBEntities db = new DemoDBEntities(); // GET api/EmployeeApi public IEnumerable<Employees> GetEmployees() { return db.Employees.AsEnumerable(); } // GET api/EmployeeApi/5 public Employees GetEmployees(int id) { Employees employees = db.Employees.Find(id); if (employees == null) { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); } return employees; } // PUT api/EmployeeApi/5 public HttpResponseMessage PutEmployees(int id, Employees employees) { if (ModelState.IsValid && id == employees.EmployeeID) { db.Entry(employees).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { return Request.CreateResponse(HttpStatusCode.NotFound); } return Request.CreateResponse(HttpStatusCode.OK); } else { return Request.CreateResponse(HttpStatusCode.BadRequest); } } // POST api/EmployeeApi public HttpResponseMessage PostEmployees(Employees employees) { if (ModelState.IsValid) { db.Employees.Add(employees); db.SaveChanges(); HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, employees); response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = employees.EmployeeID })); return response; } else { return Request.CreateResponse(HttpStatusCode.BadRequest); } } // DELETE api/EmployeeApi/5 public HttpResponseMessage DeleteEmployees(int id) { Employees employees = db.Employees.Find(id); if (employees == null) { return Request.CreateResponse(HttpStatusCode.NotFound); } db.Employees.Remove(employees); try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { return Request.CreateResponse(HttpStatusCode.NotFound); } return Request.CreateResponse(HttpStatusCode.OK, employees); } protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); } } }
在添加一個普通的控制器EmployeeController,並在里面添加如下方法:
public ActionResult Create() { return View("Create"); }
添加視圖Create.cshtml:
首先在視圖中添加對ko的引用,mapping.js是用來實現綁定viewmodel的第三方插件:
<script src="~/Scripts/knockout-2.1.0.js"></script> <script src="~/Scripts/knockout.mapping-latest.js"></script>
在body節點下添加一個form表單如下代碼:
<form> <table> <tr> <td> <!--將textbox監控屬性的值與ViewModel綁定 --> <table id="tbldml"> <tr> <td>編號</td> <td> <input type="text" id="txteno" data-bind="value: $root.EmployeeID" disabled="disabled" /></td> </tr> <tr> <td>名稱</td> <td> <input type="text" id="txtename" data-bind="value: $root.EmployeeName" /></td> </tr> <tr> <td>薪資</td> <td> <input type="text" id="txtsal" data-bind="value: $root.Salary" /></td> </tr> <tr> <td>部門</td> <td> <input type="text" id="txtdname" data-bind="value: $root.DeptName" /></td> </tr> <tr> <td>籍貫</td> <td> <input type="text" id="txtdesig" data-bind="value: $root.Address" /></td> </tr> <tr> <!--ko控制的保存和修改按鈕--> <td> <button data-bind="click :$root.save">保存</button></td> <td> <button data-bind="click: $root.update">修改</button></td> </tr> </table> </td> <td> <div class="FixedContainer"> <!--控制有數據的時候顯示表格--> <table data-bind="visible: Employees().length>0"> <thead> <tr> <td>編號</td> <td>名稱</td> <td>薪資</td> <td>部門</td> <td>籍貫</td> <td></td> </tr> </thead> <!--遍歷所有數據-> <tbody data-bind="foreach: Employees"> <tr style="border: solid" data-bind="click: $root.getselectedemployee" id="updtr"> <td><span data-bind="text: EmployeeID"></span></td> <td><span data-bind="text: EmployeeName"></span></td> <td><span data-bind="text: Salary"></span></td> <td><span data-bind="text: DeptName"></span></td> <td><span data-bind="text: Address"></span></td> <td> <button data-bind="click: $root.deleterec">Delete</button></td> </tr> </tbody> </table> </div> </td> </tr> </table> </form>
4、頁面改造好以后,編寫Ko需要的js來實現增刪改查
在頁面添加scripts占位節點添加如下腳本:
@section scripts{ <script type="text/javascript"> var EmpViewModel = function () { var self = this; self.EmployeeID = ko.observable("0"); self.EmployeeName = ko.observable(""); self.Salary = ko.observable(""); self.DeptName = ko.observable(""); self.Address = ko.observable(""); var EmpData = { EmployeeID: self.EmployeeID, EmployeeName: self.EmployeeName, Salary: self.Salary, DeptName: self.DeptName, Address: self.Address }; //生命一個ObservableArray來存儲返回的所有數據 self.Employees = ko.observableArray([]); GetEmployees(); //通過ajax請求返回所有數據 //保存數據 self.save = function () { //Ajax 提交到webapi保存數據 alert(11); $.ajax({ type: "POST", url: "/api/EmployeeApi", data: ko.toJSON(EmpData), contentType: "application/json", success: function (data) { alert("記錄保存成功"); self.EmployeeID(data.EmployeeID); alert("新數據Id :" + self.EmployeeID()); GetEmployees(); }, error: function () { alert("提交失敗"); } }); }; self.update = function () { var url = "/api/EmployeeApi/" + self.EmployeeID(); alert(url); $.ajax({ type: "PUT", url: url, data: ko.toJSON(EmpData), contentType: "application/json", success: function (data) { alert("修改成功"); GetEmployees(); }, error: function (error) { alert(error.status + "<!----!>" + error.statusText); } }); }; //刪除操作 self.deleterec = function (employee) { $.ajax({ type: "DELETE", url: "/api/EmployeeApi/" + employee.EmployeeID, success: function (data) { alert("Record Deleted Successfully"); GetEmployees();//Refresh the Table }, error: function (error) { alert(error.status + "<--and--> " + error.statusText); } }); }; //獲取所有Employee function GetEmployees() { //Ajax 獲取所有Employee記錄 $.ajax({ type: "GET", url: "/api/EmployeeApi", contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { self.Employees(data); }, error: function (error) { alert(error.status + "<--and--> " + error.statusText); } }); } //點擊右側列表某一行左側編輯賦值 self.getselectedemployee = function (employee) { self.EmployeeID(employee.EmployeeID), self.EmployeeName(employee.EmployeeName), self.Salary(employee.Salary), self.DeptName(employee.DeptName), self.Address(employee.Address) }; }; //激活knockout ko.applyBindings(new EmpViewModel()); </script> }
代碼中有比較詳細的注釋,其中實現的增刪查改的操作是通過ajax異步調用webapi來實現的,刷新及數據綁定是通過ko來實現的。
5、運行程序得到如下效果:

新增記錄的時候id默認為0,表單數據為空,點擊保存實現無刷新保存,右側若無數據表格則隱藏,若有數據表格顯示數據列表。
點擊某一行數據,左側表單顯示該行數據信息,並可以修改信息
點擊刪除實現無刷新刪除數據記錄。
