Can you call ko.applyBindings to bind a partial view?

AjaxHtmlknockout.js

Ajax Problem Overview


I'm using KnockoutJS and have a main view and view model. I want a dialog (the jQuery UI one) to popup with another view which a separate child view model to be bound to.

The HTML for the dialog content is retrieved using AJAX so I want to be able to call ko.applyBindings once the request has completed, and I want to bind the child view model to just the portion of the HTML loaded via ajax inside the dialog div.

Is this actually possible or do I need to load ALL my views and view models when the page initially loads and then call ko.applyBindings once?

Ajax Solutions


Solution 1 - Ajax

ko.applyBindings accepts a second parameter that is a DOM element to use as the root.

This would let you do something like:

<div id="one">
  <input data-bind="value: name" />
</div>

<div id="two">
  <input data-bind="value: name" />
</div>

<script type="text/javascript">
  var viewModelA = {
     name: ko.observable("Bob")
  };

  var viewModelB = {
     name: ko.observable("Ted")
  };

  ko.applyBindings(viewModelA, document.getElementById("one"));
  ko.applyBindings(viewModelB, document.getElementById("two"));
</script>

So, you can use this technique to bind a viewModel to the dynamic content that you load into your dialog. Overall, you just want to be careful not to call applyBindings multiple times on the same elements, as you will get multiple event handlers attached.

Solution 2 - Ajax

While Niemeyer's answer is a more correct answer to the question, you could also do the following:

<div>
  <input data-bind="value: VMA.name" />
</div>

<div>
  <input data-bind="value: VMB.name" />
</div>

<script type="text/javascript">
  var viewModels = {
     VMA: {name: ko.observable("Bob")},
     VMB: {name: ko.observable("Ted")}
  };

  ko.applyBindings(viewModels);
</script>

This means you don't have to specify the DOM element, and you can even bind multiple models to the same element, like this:

<div>
  <input data-bind="value: VMA.name() + ' and ' + VMB.name()" />
</div>

Solution 3 - Ajax

I've managed to bind a custom model to an element at runtime. The code is here: http://jsfiddle.net/ZiglioNZ/tzD4T/457/

The interesting bit is that I apply the data-bind attribute to an element I didn't define:

    var handle = slider.slider().find(".ui-slider-handle").first();
    $(handle).attr("data-bind", "tooltip: viewModel.value");
    ko.applyBindings(viewModel.value, $(handle)[0]);

Solution 4 - Ajax

You should look at the with binding, as well as controlsDescendantBindings http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCharlieView Question on Stackoverflow
Solution 1 - AjaxRP NiemeyerView Answer on Stackoverflow
Solution 2 - AjaxmhuView Answer on Stackoverflow
Solution 3 - AjaxZiglioUKView Answer on Stackoverflow
Solution 4 - AjaxSam JacobsView Answer on Stackoverflow