Gnurfos
Gnurfos

Reputation: 1010

Knockoutjs: dynamic content and applyBindings

I am "dynamically" populating my page like this:

<script type="text/html" id="ContainerTemplate">
  <span data-bind="template: {
                     name: contentTemplate,
                     data: contentData }"></span>
</script>

<script type="text/html" id="fooTemplate">
  <span data-bind="text: barAttribute"></span>
</script>

<button data-bind="click: complete">complete</button>

Hello
<span data-bind="template: { name: 'ContainerTemplate', foreach: myContents }"></span>
!

ViewModel:

var viewModel = {
    myContents: ko.observableArray([]),
    complete: function() {
        viewModel.myContents.push({
            contentTemplate:'fooTemplate',
            contentData:{barAttribute:'world'}});
    }
};

ko.applyBindings(viewModel);

A particularity is that template names are dynamic. It seems to work like this (you can try it on http://jsfiddle.net/hPQNx/ ), but I wonder if I'm doing things correctly. Some template features like root or parent don't seem to be working.

Should I manually re-call applyBindings at some point ? I have seen this must be done on the related DOM nodes, but how can I access those nodes in my setup ?

Upvotes: 4

Views: 3504

Answers (1)

John Papa
John Papa

Reputation: 22298

I added a property to your view model and showed how you can add a root property and reference it with $root and $parent can work here in this fiddle.

var viewModel = {
    a: ko.observable('foo'),
    myContents: ko.observableArray([]),
    complete: function() {
        viewModel.myContents.push({
            contentTemplate: 'fooTemplate',
            b: 'goo',
            contentData: {
                barAttribute: 'world'
            }
        });
    }
};

ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.0.0/knockout-min.js"></script>
<script type="text/html" id="ContainerTemplate">
  <span data-bind="template: {
                     name: contentTemplate,
                     data: contentData }"></span>
</script>
      
<script type="text/html" id="fooTemplate">
  <span data-bind="text: barAttribute"></span>
  <div data-bind="text: $root.a"></div>
  <div data-bind="text: $parent.b"></div>
</script>

<button data-bind="click: complete">complete</button>

Hello
<span data-bind="template: { name: 'ContainerTemplate', foreach: myContents }"></span>
!

Upvotes: 4

Related Questions