Jake N
Jake N

Reputation: 10583

KnockoutJS apply binding to form returned from Ajax

I have a button thats applied to the DOM after an ajax

<input type="submit" data-bind="click: save" />

The save call is not triggered from without my ViewModel, presumably Knockout is not aware from this new binding within the DOM.

 var Model = function()
 {
      this.save = function(data, event)
      {
           alert("test");
      }
 }

How can I reapply the binding so that this new HTML is picked up and the save binding works?

Upvotes: 0

Views: 882

Answers (2)

Adam Diament
Adam Diament

Reputation: 4830

An alternative, perhaps more 'knockouty' approach to this would be to have the button present the whole time, but use use bindings to control the visiblity of the button.

e.g

<input type="submit" data-bind="click: save, visible: anObservableValue" />

where anObservableValue is a ko.observable(false) that you set to true with
anObservableValue(true) when you have done the inital ajax call you mentioned.

Alternatively if it is important that the button is not actually present in the dom before you make the ajax call, then use the knockout if binding wrapped around the button

<!-- ko if: anObervableValue -->
    <input type="submit" data-bind="click: save" />
<!-- /ko -->

that way the button will only be present in the dom when you want it to be, but knockout will handle the binding and will know about your save method right from the start.

This will avoid all of the fiddly binding multiple times stuff, that personally I only do when I absolutely have to

Upvotes: 0

manji
manji

Reputation: 47968

After loading new content, you can apply bindings to the save button, with the part of your model that contains the save method, using ko.applyBindings(model, targetElement):

Example:

var vm = {
    load: function() {
        // insert new content
        document.getElementById('container').innerHTML = 
        '<input id="btLoad" \
                type="button" value="save" \
                data-bind="click: save" />';
        
        // apply bindings to new elements
        ko.applyBindings(vm, document.getElementById('btLoad'));
    },
    save: function() {
        alert('saved');
    }
};

ko.applyBindings(vm);
<script 
 src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js">
</script>

<input type="button" value="load" data-bind="click: load"/>
<div id="container">
</div>

Upvotes: 1

Related Questions