2

In a (webforms) page I have a button that opens a jqueryui dialogue which is loaded dynamically.
The problem is that I want this dialogue to be master of its own knockout view model but the view model is already set in the main page.

I suppose it is not possible to add new properties to the view model after ko.applyBindings is called.
Instead I should be looking into another design. But which?

  • Applying bindings to different parts of the DOM would require me to some big redesigns I hope to avoid right now.
  • Having all the dialoge bindings as a list of key-values is possible but not very elegant IMHO. The main page would then only have to add a vm.dialogueKeyvalueCollection.
  • My present, possible, solution is to have the main form add the dialogue's properties vm.dialogue.userName() vm.dialogue.searchResult() but then my html controls won't bind as they are created after applyBindings is called. The present solution for this is to call ApplyBindings again like so: ko.applyBindings(vm, $('#dialog-form')[0]); for the added HTML. I was in the belief (and still somewhat am) that to call applyBindings for different DOM elements one must not be nested inside another. Binding to dynamic HTML is commented here and jsfiddled here.
  • ?
Community
  • 1
  • 1
LosManos
  • 7,195
  • 6
  • 56
  • 107
  • 1
    I have noticed, through trial and horror, that it is ok to call `applyBindings(vm, domElement)` on a newly created part of the DOM. My guess is that once a control has been bound it cannot be again; while new DOM elements have never been bound so binding them is ok. I guess, as I have not tried, that the new elements/DOM tree must be placed at an existing leaf since traversing this new DOM must not traverse into already bound elements. _Was this at all understandable?_ – LosManos Feb 21 '15 at 20:01

2 Answers2

2

I do a lot of composition with nested view models, often for the purpose of creating dialogues modals. See here for a full-fledged answer.

It might be simpler to try and get away with just using the with binding, though. You could create a dialogueViewmodel observable property on your viewmodel.

Just fill it with one or more observable keys when you're ready to show the dialogue, such as

this.dialogueViewmodel({
  markup: ko.observable("<h1>Kittens!</h1>")
});

and wrap it in a with binding:

<!-- ko with: dialogueViewmodel -->
  <div id="dialog" title="Basic dialog" data-bind="html: markup">
  </div>
<!-- /ko -->

As long as dialogueViewmodel is null, nothing gets bound and rendered. This only happens when you add your dialogue data - no need to fiddle with applyBindings again.

You will probably have to write your own binding to interface with jQueryUI.dialogue, though.

Third option: I have written a modal library that comes with a Knockout binding out of the box. Here's a JSfiddle demo. If you're not set on jQueryUI, that might be an alternative; while the documentation is not perfect, I'd be happy to help you any way I can and fix the docs along the way.

Community
  • 1
  • 1
janfoeh
  • 10,243
  • 2
  • 31
  • 56
  • I didn't know what `width` did, had only seen it in text but not looked into it. Looks promising. Might be the Answer I was looking for but not until I have tested it myself. At the time of writing I (unfortunately) have decided on a more crude solution. I will hopefully remember to keep this post updated as I continue and learn. – LosManos Feb 21 '15 at 19:55
0

Can you ko.applyBindingsToNode function to bind the appended html.

ko.applyBindingsToNode(appendedelement,{ binding options})

Hope this will help you.

Anil Talla
  • 709
  • 5
  • 19
  • Is applyBindingsToNode from [Sharpkit](http://sharpkit.net/help/SharpKit.KnockoutJs/SharpKit.KnockoutJs/Knockout/applyBindingsToNode(HtmlElement,JsObject,Object,JsString).htm)? – LosManos Feb 21 '15 at 19:49