3

At first, I have a Button addTemplate that will add html to my body via Knockout and jQuery:

<button data-bind="click: addTemplate">Add Template</button>

<script type="text/html" id="MyTemplate">
    <div id="container">
        <a href="#" data-bind="click: $root.doAlert">Do Alert</a>
    </div>
</script>

The added Template has some knockout Bindings, too. They should activate an Alert in my ViewModel:

function MyViewModel()
{
    self = this;

    self.addTemplate = function () {
        $($("#MyTemplate").html()).appendTo("body");
    }

    self.doAlert = function() {
        alert('Hello World');
    } 
}

ko.applyBindings(new MyViewModel());

When I click on the Link in my added Template, the doAlert function does nothing. I do not want to use string-chained HTML Templates in my ViewModel.

Here is the Fiddle: http://jsfiddle.net/tgu8C/5/

Simon
  • 4,157
  • 2
  • 46
  • 87
  • possible duplicate of [KnockoutJS: ko.applyBindings to partial view?](http://stackoverflow.com/questions/7342814/knockoutjs-ko-applybindings-to-partial-view) – PW Kad Nov 04 '13 at 12:29
  • That answer gives you what you need to apply bindings to a specific portion of your page that wasn't available at first run – PW Kad Nov 04 '13 at 12:30

2 Answers2

1

You should apply binding to newly added element.

var newElement = $($("#MyTemplate").html()).appendTo("body");
ko.applyBindings(self, newElement);  

JSFiddle DEMO

Ilya
  • 29,135
  • 19
  • 110
  • 158
0

Without a broader understanding of the context of the problem which you are trying to solve I could be barking up the wrong tree. However, I suspect you are tackling the problem in the wrong way. You should never need to repeatedly add the template to the DOM. Using Knockout templates as they were intended will do this for you. May I suggest the following model...

function MyViewModel() {
    var self = this;

    self.items = ko.observableArray([]);

    self.add = function () {
        self.items.push({});
    };

    self.doAlert = function() {
        alert('Hello World');
    } 
}

ko.applyBindings(new MyViewModel());

... accompanied with the following markup ...

<button data-bind="click: add">Add Template</button>
<!-- ko template: { name: 'myTemplate', foreach: items } -->
<!-- /ko -->
<script type="text/html" id="myTemplate">
    <div class="container">
        <a href="#" data-bind="click: $root.doAlert">Do Alert</a>
    </div>
</script>

I should also point out that I've replaced the id of the container with a CSS class as this makes much more sense.

Michael Papworth
  • 453
  • 3
  • 11