jQuery UI dialogs are a very useful way of displaying detail data but if you have a few of them nested in your view then Knockout JS data-binding requires some planning. The ko.applyBindings function can take a html element object as a second parameter and then it applies the binding to every element with a data-bind attribute in that scope. jQuery UI dialogs are div elements that may be nested within other elements that display the higher level data items. Consider the following example;
<div id="OrdersDiv">
<input id="OrderIdText" type="text" data-bind="value: OrderId"/>
<input id="CustomerNameText" type="text" data-bind="value: CustomerName"/>
<a id="DialogLink" href="#" >Click here to see order details</a>
<div id="OrderDetailsDialog">
<input id="ProductNameText" type="text" data-bind="value: ProductName"/>
</div>
</div>
<script type="text/javascript">
var OrderViewModel = function () {
var OrderId = ko.observable();
var CustomerName = ko.observable();
}
$(document).ready(function () {
$("#OrderDetailsDialog").dialog();
var order = new OrderViewModel ();
ko.applyBindings (order, document.getElementById ("OrdersDiv"));
}
</script>
This code won't work since the OrdersViewModel doesn't have a ProductName property. One way to handle this problem is to create a view model object that contains the order details data as well. But this may result in unnecessary data transfer. We can create a custom binding to prevent KO from binding to child elements and then bind the child elements to the details view model as below;
<div id="OrdersDiv">
<input id="OrderIdText" type="text" data-bind="value: OrderId"/>
<input id="CustomerNameText" type="text" data-bind="value: CustomerName"/>
<a id="DialogLink" href="#" >Click here to see order details</a>
<div id="DetailsDiv" data-bind="stopBindings: true">
<div id="OrderDetailsDialog">
<input id="ProductNameText" type="text" data-bind="value: ProductName"/>
</div>
</div>
</div>
<script type="text/javascript">
var OrderViewModel = function () {
var OrderId = ko.observable();
var CustomerName = ko.observable();
}
var OrderDetailsViewModel = function () {
var OrderId = ko.observable();
var ProductName = ko.observable();
}
$(document).ready(function () {
$("#OrderDetailsDialog").dialog();
ko.bindingHandlers.stopBindings = {
init: function () {
return { 'controlsDescendantBindings': true };
}
};
var order = new OrderViewModel ();
var orderDetail = new OrderDetailsViewModel();
ko.applyBindings (order, document.getElementById ("OrdersDiv"));
ko.applyBindings (orderDetail, document.getElementById ("OrderDetailsDialog"));
}
</script>
Reference: Knockout ignore binding, for nested viewModels?
No comments:
Post a Comment