經過Knockout.js + ASP.NET Web API構建一個簡單的CRUD應用

REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.htmljavascript

 

較之面向最終消費者的網站,企業級Web應用對用戶體驗的要求要低一些。不過客戶對「用戶體驗」的要求是「與日俱增」的,不少被「慣壞了」的用戶已經不能忍受Postback帶來的頁面刷新,因此Ajax在企業級Web應用中獲得了普遍的應用。企業級Web應用的一個特色是以「數據處理」爲主,因此「面向綁定」的Knockout.js 是一個不錯的選擇。ASP.NET Web API,做爲.NET平臺最好的REST服務開發平臺(主要與WCF相比),則能夠以服務的形式提供對數據的後臺處理。css

1、一個簡單的基於CRUD的Web應用

在《經過ASP.NET Web API + JQuery建立一個簡單的Web應用》中,我採用jQuery + ASP.NET Web API構建了一個單純的對單一數據進行CRUD操做的應用,對於數據在界面上的呈現,我是經過jQuery 動態生成HTML的方式實現的。如今咱們經過Knockout.js來進行數據綁定,你會發現咱們代碼會變得很優雅。html

這個簡單的Demo應用用於模擬「聯繫人管理」。當頁面加載的時候,全部的聯繫人列表被列出來。在同一個頁面中,咱們能夠添加一個新的聯繫人,也能夠修改和刪除現有聯繫人信息。整個應用惟一的頁面在瀏覽器中的呈現效果以下圖所示。java

image

2、經過ASP.NET Web API提供服務

先來看看ApiController的定義。以下面的代碼片段所示,咱們定義了一個名爲ContactsController的ApiController用於完成針對聯繫人的CRUD操做,咱們採用HTTP Method(Get、Post、Put和Delete)對Action方法進行命名,由於在進行Action匹配的時候會默認以Http Method做爲前綴進行匹配。jquery

   1: public class ContactsController : ApiController
   2: {
   3:     private static List<Contact> contacts = new List<Contact>
   4:     {
   5:         new Contact{ Id = "001", FirstName = "San", LastName="Zhang", PhoneNo="123", EmailAddress="zhangsan@gmail.com"},
   6:         new Contact{ Id = "002", FirstName = "Si", LastName="Li", PhoneNo="456", EmailAddress="lisi@gmail.com"}
   7:     };
   8:  
   9:     public IEnumerable<Contact> Get()
  10:     {
  11:         return contacts;
  12:     }
  13:  
  14:     public Contact Get(string id)
  15:     {
  16:         return contacts.FirstOrDefault(c => c.Id == id);
  17:     }
  18:  
  19:     public void Put(Contact contact)
  20:     {
  21:         contact.Id = Guid.NewGuid().ToString();
  22:         contacts.Add(contact);
  23:     }
  24:  
  25:     public void Post(Contact contact)
  26:     {
  27:         Delete(contact.Id);
  28:         contacts.Add(contact);
  29:     }
  30:  
  31:     public void Delete(string id)
  32:     {
  33:         Contact contact = contacts.FirstOrDefault(c => c.Id == id);
  34:         contacts.Remove(contact);
  35:     }
  36: }
  37:  
  38: public class Contact
  39: {
  40:     public string Id { get; set; }
  41:     public string FirstName { get; set; }
  42:     public string LastName { get; set; }
  43:     public string PhoneNo { get; set; }
  44:     public string EmailAddress { get; set; }
  45: }

和ASP.NET MVC Web應用同樣,咱們一樣採用URL路由機制來實現請求地址與目標Controller和Action的映射,而針對API默認註冊的路有以下所示(這裏調用的方法是MapHttpRoute而不是MapRoute)。web

   1: public class RouteConfig
   2: {
   3:     public static void RegisterRoutes(RouteCollection routes)
   4:     {
   5:         routes.MapHttpRoute(
   6:             name: "DefaultApi",
   7:             routeTemplate: "api/{controller}/{id}",
   8:             defaults: new { id = RouteParameter.Optional }
   9:         );
  10:     }
  11: }

按照註冊的路由規則和Action方法名稱與HTTP方法的默認影射機制,咱們能夠直接在瀏覽器中分別訪問地址「/api/contacts」和「/api/contacts/001」獲得全部聯繫人列表和ID爲「001」的聯繫人信息。獲得的結果以下圖所示。ajax

image

3、經過jQuery進行Ajax調用,利用Knockout.js進行數據綁定

咱們經過ASP.NET MVC來構建Web應用,默認的HomeController定義以下,默認的Index操做僅僅是將默認的View呈現出來而已。api

   1: public class HomeController : Controller
   2: {
   3:     public ActionResult Index()
   4:     {
   5:         return View();
   6:     }
   7: }

下面是整個View的定義。咱們採用jQuery進行Ajax調用ApiController進行聯繫人的獲取、添加、修改和刪除,數據和命令(添加、修改和刪除)的綁定是經過Knockout.js來完成的。瀏覽器

   1: <!DOCTYPE html>
   2: <html lang="en">
   3:     <head>
   4:         <title>@ViewBag.Title - My ASP.NET MVC Application</title>
   5:         @Styles.Render("~/Content/css" )
   6:         <script type="text/javascript" src="../../Scripts/jquery-1.6.2.min.js"></script>
   1:  
   2:         <script type="text/javascript" src="../../Scripts/knockout-2.0.0.js">
   1: </script>       
   2:     </head>
   3:     <body>
   4:     <div id="contacts">
   5:          <table>
   6:             <tr>
   7:                 <th>First Name</th>
   8:                 <th>Last Name</th>
   9:                 <th>Phone No.</th>
  10:                 <th>Email Address</th>
  11:                 <th></th>
  12:             </tr>
  13:             <tbody>
  14:                 <!-- ko foreach: contacts -->
  15:                 <tr>
  16:                     <td data-bind="text: FirstName" />
  17:                     <td data-bind="text: LastName" />
  18:                     <td data-bind="text: PhoneNo" />
  19:                     <td><input type="text" class="textbox long" data-bind="value: EmailAddress" /></td>
  20:                     <td>
  21:                         <a href="#" data-bind="click: $root.updateContact">Update</a><a href="#" data-bind="click: $root.deleteContact">Delete</a>
  22:                     </td>
  23:                 </tr>
  24:                 <!-- /ko -->
  25:                 <tr data-bind="with: addedContact">
  26:                     <td><input type="text" class="textbox" data-bind="value: FirstName"</td>
  27:                     <td><input type="text" class="textbox" data-bind="value: LastName"</td>
  28:                     <td><input type="text" class="textbox" data-bind="value: PhoneNo"</td>
  29:                     <td><input type="text" class="textbox long" data-bind="value: EmailAddress"</td>
  30:                     <td><a href="#" data-bind="click: $root.addContact">Add</a></td>
  31:                 </tr>
  32:             </tbody>
  33:         </table>
  34:     </div>
  35:     <script type="text/javascript" >
  36:         function contactManagerModel() {
  37:             self = this;
  38:             self.contacts = ko.observableArray();
  39:             self.addedContact = ko.observable();
  40:  
  41:             self.loadContacts = function () {
  42:                 $.get("/api/contacts", null, function (data) {
  43:                     self.contacts(data);
  44:                     var emptyContact = { Id: "-1", FirstName: "", LastName: "", PhoneNo: "", EmailAddress: "" };
  45:                     self.addedContact(emptyContact);
  46:                     $("table tr:odd").addClass("oddRow");
  47:                 });
  48:             };
  49:  
  50:             self.addContact = function (data) {
  51:                 if (!self.validate(data)) {
  52:                     return;
  53:                 }
  54:                 $.ajax({
  55:                     url: "api/contacts/",
  56:                     data: self.addedContact(),
  57:                     type: "PUT",
  58:                     success: self.loadContacts
  59:                 });
  60:             };
  61:  
  62:             self.updateContact = function (data) {
  63:                 $.ajax({
  64:                     url: "api/contacts/" + data.Id,
  65:                     data: data,
  66:                     type: "POST",
  67:                     success: self.loadContacts
  68:                 });                        
  69:             };
  70:  
  71:             self.deleteContact = function (data) {
  72:                 $.ajax({
  73:                     url: "api/contacts/" + data.Id,
  74:                     type: "DELETE",
  75:                     success: self.loadContacts
  76:                 });
  77:             };
  78:  
  79:             self.validate = function (data) {
  80:                 if (data.FirstName && data.LastName && data.PhoneNo && data.EmailAddress) {
  81:                     return true;
  82:                 }
  83:                 alert("Please provide complete contact information!");
  84:                 return false;
  85:             }
  86:             self.loadContacts();
  87:         }
  88:         ko.applyBindings(new contactManagerModel());
  89:     
</script>
   7:     </body>
   8: </html>
相關文章
相關標籤/搜索