一、完整的Demo
1.1 服務端
Demo所用數據存儲於sql server,表結構與關係如圖1所示,涉及班級表和學生表(一對多關係)兩個表。
表1 數據表結構及關係
服務端與SQL的數據交互利用.Net之EF框架,生成的Model中Calsse與Student存在主外鍵約束,為了避免在序列化時的循環引用錯誤,引入Newtonsoft.Json(可以NuGet添加),在Student中添加以下代碼(如果以獲取Student數據為重點,在Calsse類中Stuent屬性添加JsonIgnore):
[JsonIgnore]
public virtual Classe Classe { get; set; }
加入JsonIgnore後,在序列化過程中將會忽略掉該屬性。
為了讀取數據,新建Controllers文件夾並添加Web Api控制器類ClassInfoControllers,在Global中註冊WebApi(關於WebApi)。在ClassInfoControllers添加如下方法:
public class ClassInfoController : ApiController
{
// GET api/<controller>
public ManuModel Get()
{
var context = new ModelTestEntities1();
var model = new ManuModel {Classes = context.Classe.ToList()};
return model;
}
}
其中,ManuModel是對實體類的包裝(為了前端Mapping),代碼如下:
public class ManuModel
{
public IEnumerable<Classe> Classes { get; set; }
}
1.2 Web前前端
新建Html頁面,引入JQuery、knockout、mapping對應的js文件。添加如下JavaScript代碼:
在MVVM中最好是VM與View之間單一依賴,在Js中不出現dom對象。Html代碼如下:<script> $(function () { $.ajax({ type: "GET", url: "api/ClassInfo", dataType: "json", async: false, cache: false, success: function (data) { var mapping = { 'Student': { update: function (option) { var mid = option.data; if (option.data) { mid.Birthday = option.data.Birthday.toString().split('T')[0]; } return mid; }, create: function (option) { var mid = option.data; mid.Age = ko.computed(function () { var year = (new Date()).getYear() + 1900; var newy = parseInt(mid.Birthday); return year-newy; }); return mid; } } }; var viewModel = ko.mapping.fromJS(data, mapping); ko.applyBindings(viewModel); } }); }) </script>
至此工作完成,在瀏覽器中查看,結果如圖2所示。<div data-bind="foreach:Classes"> <div> <div style="background-color: #f0e68c; width: 20%"><span data-bind="text:Name"></span></div> <div> <table> <thead> <tr> <td>姓名</td> <td>性别</td> <td>出生年月</td> <td>年齡</td> </tr> </thead> <tbody data-bind="foreach:Student"> <tr> <td><span data-bind="text:Name"></span></td> <td><span data-bind="text:Sex"></span></td> <td><span data-bind="text:Birthday"></span></td> <td><span data-bind="text:Age"></span></td> </tr> </tbody> </table> </div> </div> </div>
圖2 Demo演示結果
二、基於Demo對mapping擴展的理解
從Demo來看,发起請求後從服務器取得Json對象數據,mapping將其轉為可監視的js对象,其对应关系如图3所示它們的對應關係也一目了然了,明白了mapping後的結構,create、update、key等mapping關鍵詞(屬性)的用法也就比較明確了。
圖3 服務端類與web前端VM的對應關係
寫在後面的:第一次寫博客記錄自己學習的東西,寫博客是個體力活也是腦力活,寫到後面有點煩躁就草草結束了,希望自己能堅持寫下去。