Reputation: 9451
Say that we have a simple model and view model:
// Model
function Model(prop) {
this.Prop = ko.observable(prop);
}
// View Model
function ViewModel(){
var self = this;
this.CurrentItem = ko.observable(new Model("abc"));
this.Edit = function(){
$(#"EditDiv").dialog("show");
}
}
Then the html:
<body>
<input type="button" data-bind="click: Edit"/>
<div id="EditDiv" data-bind="with: CurrentItem">
<input type="text" data-bind="value: Property" />
</div>
</body>
Then the script at the bottom of the page:
$(document).ready(function(){
$("#EditDiv").dialog({ /* settings to hide it first. */ });
ko.applyBindings(new ViewModel());
});
The above code works, and will pop up a jQuery window with a text box with text "abc".
However, if I divide the page in divs and assign a different model view to each div, the binding breaks:
<body>
<div id="ForAnotherBindingContextDiv">
</div>
<div id="TargetContextDiv">
<input type="button" data-bind="click: Edit"/>
<div id="EditDiv" data-bind="with: CurrentItem">
<input type="text" data-bind="value: Property" />
</div>
</div>
</body>
So now we change the binding to:
ko.applyBindings(new ViewModel(), $("#TargetContextDiv")[0]);
The above will still popup the edit window, however, the text box is empty. To me, this looks like the binding is broken because jQuery places the entire dialog setup at the document's root level when we call .dialog("show"), which is now outside the context of the ViewModel
.
Does jQuery have an option for not putting the whole dialog fix at the root level? Is there a different approach that I can take? (I also tried the custom binding route, and it wouldn't bind either. It works if the contents of such a div is static (without bindings), like an error message text).
Upvotes: 0
Views: 5292
Reputation: 17554
I have a dialog binding in my collection of bindings. Much better to abstract the DOM from the logic
https://github.com/AndersMalmgren/Knockout.Bindings
Demo http://jsfiddle.net/H8xWY/130/
<div id="dialog" data-bind="dialog: { autoOpen: false, modal: true, title: dialogTitle }, template: { name: 'dialog-template', data: dialogItem, 'if': dialogItem }, openDialog: dialogItem"></div>
Upvotes: 5