knockout.jsko-custom-binding

Can I dynamically bind element inside custom binding?


is there a way to bind elements from inside of custom binding? For example I have custom binding and bind to it observable array of items:

var someArrayOfItems = ko.observableArray(['item1', 'item2', 'item3']);
...
<div data-bind="myBinding: someArrayOfItems"></div>

Now I would like myBinding to list all the elements from 'someArrayOfItems' inside the div element it was bound to like:

<ul data-bind="foreach: someArrayOfItems">
    <li>
        <span data-bind="text: $data"></span>
    </li>
</ul>

Is it possible to make such operation using a custom binding? Thanks for any help.


Solution

  • You can use the function ko.applyBindingsToNode to dynamically add a binding to an element.

    In your case, you would need to also populate the contents with an appropriate "template".

    For example, you could do something like:

    ko.bindingHandlers.myBinding = {
        init: function(element, valueAccessor) {
            var ul = document.createElement("ul"),
                data = valueAccessor();
    
            //append a new ul to our element
            element.appendChild(ul);
    
            //could use jQuery or DOM APIs to build the "template"
            ul.innerHTML = "<li><span data-bind='text: $data'></span></li>";
    
            //apply foreach binding to the newly created ul with the data that we passed to the binding
            ko.applyBindingsToNode(ul, { foreach: data });;
    
            //tell Knockout that we have already handled binding the children of this element
            return { controlsDescendantBindings: true };
        }        
    };
    

    Sample here: http://jsfiddle.net/rniemeyer/z458E/