I\'m trying to get Knockout components to bind after the initial ko.applyBindings();
so I can add custom elements dynamicall
The component binding doesn't happen magically: it happens when you call ko.applyBindings();
. At this moment, the bound HTML is searched for components, and they are bound.
Later on, when you dynamically add a new component to the page, it's not bound, unless you explicitly bind it. So, in your code, the component is fully ignored.
As stated, what you need to do is to explicitly bind it. But you must take into account that you cannot bind nodes that have already been bound. However it's extremely easy to create a node with jquery, append it to the DOM, and bind it. There is a syntax to specify the viewmodel and the node to which you want to bind it: ko.applyBindings(viewModel, node);
Here you have a full working sample in jsfiddle. This is the code in that fiddle:
HTML:
Here's a widget, declared inline:
<button id='btnAdd'>Add a new widget to the grey box:</button>
<br/><br/>
<div id='addZone' class="well">
Widgets will be appended here
</div>
JavaScript:
ko.components.register('like-widget', {
template: '<div class="alert alert-info">This is the widget</div>'
});
ko.applyBindings()
$('#btnAdd').on('click', function() {
// Create your widget node
var $newWidget = $('<like-widget>');
// Append it to your "append area"
$('#addZone').append($newWidget);
// Apply bindings to the newly added node
ko.applyBindings({}, $newWidget[0]);
});
NOTE: when calling apply bindings I pass an empty objet: don't pass a null, or you'll get an error. If your template includes a viewmodel, it will be used independently of the passed view model.
NOTE: $newWidget is a jquery object. $newWidget[0] is the first (and only, in this case) DOM element of the jQuery object, as required by applyBindings