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
在《經過ASP.NET Web API + JQuery建立一個簡單的Web應用》中,我採用jQuery + ASP.NET Web API構建了一個單純的對單一數據進行CRUD操做的應用,對於數據在界面上的呈現,我是經過jQuery 動態生成HTML的方式實現的。如今咱們經過Knockout.js來進行數據綁定,你會發現咱們代碼會變得很優雅。html
這個簡單的Demo應用用於模擬「聯繫人管理」。當頁面加載的時候,全部的聯繫人列表被列出來。在同一個頁面中,咱們能夠添加一個新的聯繫人,也能夠修改和刪除現有聯繫人信息。整個應用惟一的頁面在瀏覽器中的呈現效果以下圖所示。java
先來看看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
咱們經過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>