我们创建一个Knockout模版,如下。Script标签的类型为text/html,包含各种内容与数据绑定标签。
<script type="text/html" id="OrderDetailTemplate">
<tr data-bind="style: { background: viewModel.SetBackgroundColor($data) }">
<td style="height:25px"><div data-bind="text:ProductID"></div></td>
<td><div data-bind="text: ProductName"></div></td>
<td>
<div data-bind="text: Quantity, visible:DisplayMode "></div>
<div data-bind="visible: EditMode" >
<input type="text" data-bind="value: Quantity" style="width: 50px" />
</div>
</td>
<td><div data-bind="text:UnitPrice"></div></td>
<td><div data-bind="text: QuantityPerUnit"></div></td>
<td><div data-bind="text: Discount, visible:DisplayMode "></div>
<div data-bind="visible: EditMode" >
<input type="text" data-bind="value:Discount" style="width:50px" />
</div>
</td>
<td>
<div data-bind="visible:DisplayDeleteEditButtons">
<div style="width:25px;float:left"><img alt="delete" data-bind="click:function()
{ viewModel.DeleteLineItem($data) }"
title="Delete item" src="@Url.Content("~/Content/Images/icon-delete.gif")"/>
</div>
<div style="width:25px;float:left"><img alt="edit" data-bind="click:function()
{ viewModel.EditLineItem($data) }" title="Edit item"
src="@Url.Content("~/Content/Images/icon-pencil.gif")"/>
</div>
</div>
<div data-bind="visible:DisplayCancelSaveButtons">
<div style="width:25px;float:left"><img alt="save" data-bind="click: function()
{viewModel.UpdateLineItem($data) }" title="Save item"
src="@Url.Content("~/Content/Images/icon-floppy.gif")"/>
</div>
<div style="width:25px;float:left"><img alt="cancel edit"
data-bind="click:function() { viewModel.CancelLineItem($data) }"
title="Cancel Edit" src="@Url.Content("~/Content/Images/icon-pencil-x.gif")"/>
</div>
</div>
</td>
</tr>
</script>
title="Delete item" src="@Url.Content("~/Content/Images/icon-delete.gif")"/>
src="@Url.Content("~/Content/Images/icon-pencil.gif")"/>
src="@Url.Content("~/Content/Images/icon-floppy.gif")"/>
data-bind="click:function() { viewModel.CancelLineItem($data) }"
title="Cancel Edit" src="@Url.Content("~/Content/Images/icon-pencil-x.gif")"/>
要想将Knockout模版添加至HTML中,只需要使用data-bind模版标签与一个foreach语句即可。
<table border="0" cellpadding="0" cellspacing="0" style="width:100%">
<tr class="DataGridHeader">
<td style="width:10%; height:25px">Product ID</td>
<td style="width:30%">Product Description</td>
<td style="width:10%">Quantity</td>
<td style="width:10%">Unit Price</td>
<td style="width:15%">UOM</td>
<td style="width:10%">Discount</td>
<td style="width:15%">Edit Options</td>
</tr>
<tbody data-bind='template: {name: "OrderDetailTemplate", foreach:LineItems}'> </tbody>
</table>
JavaScript eval函数可作JSON对象的解析。不过,由于JavaScript eval可编译并运行任何JavaScript程序,会导致安全性问题。因此,较安全的做法是使用JSON解析器。JSON解析器只识别JSON文本,而不会执行任何潜在风险的脚本。json.org网站中提供了许多JavaScript编写的JSON解析器。
使用JSON解析器,我们可以解析初始加载的订单明细数据,这些数据会与Knockout View Model实现绑定。当创建多个details line items时,我们需要创建一个数组,供Knockout监听。
initialLineItems = jsonParse($("#OrderDetailsData").text());
var viewModel = {
LineItems: ko.observableArray()
}
ko.applyBindings(viewModel);
for (i = 0; i < initialLineItems.length; i++) {
var newLineItem = CreateLineItem(initialLineItems[i]);
viewModel.LineItems.push(newLineItem);
}
var lineItemDisplay = function () {
this.ProductID;
this.ProductName;
this.Quantity;
this.UnitPrice;
this.QuantityPerUnit;
this.Discount;
this.OriginalQuantity;
this.OriginalDiscount;
this.EditMode;
this.DisplayMode;
this.DisplayDeleteEditButtons;
this.DisplayCancelSaveButtons;
};
function CreateLineItem(LineItem) {
var lineItem = new lineItemDisplay();
lineItem.ProductID = ko.observable(LineItem.ProductID);
lineItem.ProductName = ko.observable(LineItem.ProductName);
lineItem.Quantity = ko.observable(LineItem.Quantity);
lineItem.OriginalQuantity = ko.observable(LineItem.Quantity);
lineItem.OriginalDiscount = ko.observable(LineItem.Discount);
lineItem.UnitPrice = ko.observable(LineItem.UnitPrice);
lineItem.QuantityPerUnit = ko.observable(LineItem.QuantityPerUnit);
lineItem.Discount = ko.observable(LineItem.Discount);
lineItem.BackgroundColor = ko.observable(LineItem.BackgroundColor);
lineItem.EditMode = ko.observable(false);
lineItem.DisplayMode = ko.observable(true);
lineItem.DisplayDeleteEditButtons = ko.observable(true);
lineItem.DisplayCancelSaveButtons = ko.observable(false);
return lineItem;
}