Knockout custom binding handler does not update children elements

905 Views Asked by At

I'm having a problem with a custom knockout binding handler that creates a context. The demonstration is here: http://jsfiddle.net/gf3tfarz/14/

When 'container' is applied to an observable array, it's not updating the children elements.

<div data-bind="container: { data: selectedCountry().ids }">
    <p>Error: <span data-bind="text: $container.data().length"></span></p>
    <div data-bind="foreach: $container.data">
        <p>Error: <span data-bind="text: $data"></span></p>
    </div>
</div>

This is the custom binding handler:

ko.bindingHandlers.container = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var innerBindingContext = bindingContext.extend({
            $container: ko.utils.unwrapObservable(valueAccessor())
        });

        ko.applyBindingsToDescendants(innerBindingContext, element);

        return { controlsDescendantBindings: true };
    }
};

I'd like a way that both examples using 'container' present in the demonstration work.

Note that using "with" it works.

1

There are 1 best solutions below

0
On

You shouldnt be extending the bindingContext directly, you should create a child binding context. Then it will work how you expect it to.

ko.bindingHandlers.container = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {       
        // Make a modified binding context, with a extra properties, and apply it to descendant elements
        var innerBindingContext = bindingContext.createChildContext(
            bindingContext.$rawData, 
            null, // Optionally, pass a string here as an alias for the data item in descendant contexts
            function(context) {
                ko.utils.extend(context, {
                    $container: ko.utils.unwrapObservable(valueAccessor())
                });
            });

        ko.applyBindingsToDescendants(innerBindingContext, element);

        return { controlsDescendantBindings: true };
    }
};

See the bottom of this page for more info... http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html