Abraão Alves
Abraão Alves

Reputation: 803

knockoutjs: custom data-bind 'with' to pass function by reference

I have a observableArray

this.Itens = ko.obeservableArray();
this.Itens.toString = function () {return 'my items array'};

I need to pass the 'Items' property by reference to all child tags, because I have to access the methods that attached starting by children, starting from a jquery plugin:

<div data-bind="customWith: Items ">
    <ul data-bind="foreach:$data"> <!-- function reference of items -->
        <li data-bind="text: ko.toJSON($data)"></li>
    </ul>

    <br>
    <br>

    <!-- Only for debugging -->
    <p data-bind="text: ko.toJSON($data)"></p>
    <p data-bind="text: ko.toJSON($data()[0])"></p>
    <p data-bind="text: $data.fnTest"></p>
    <p data-bind="text: $data.fnTest()"></p>
</div>

Here is the custom ko.bindingHandler:

ko.bindingHandlers.customWith = {

    init: function (element, valueAccessor, allBindingsAcessor, viewModel, bindingContext) {
        ko.bindingHandlers.customWith.update.apply (this, arguments);
        $(element).myplugin ();
        return {'controlsDescendantBindings': true};
    }, 
    update: function (element, valueAccessor, allBindingsAcessor, viewModel, bindingContext) {
        var fnReference valueAccessor = ();
        var childBindingContext = bindingContext.createChildContext (fnReference);
        ko.applyBindingsToDescendants (childBindingContext, element);
    }
};

The complete code is here: http://jsfiddle.net/AbraaoAlves/fz5Yj/

As you can see inside the div tag customWith, p render the content correctly and are updated as I add or remove an item from the list, but the ul tag (foreach: $ data) does not render anything even valueAccessor the handler standing with foreach all the correct data.

What can I do to render the items in the list, in this case?

Upvotes: 1

Views: 1066

Answers (1)

CodeThug
CodeThug

Reputation: 3192

You need to move the child bindings setup to the init method of your custom binding handler. Your handler should look like this, with no update method needed:

ko.bindingHandlers.customWith = {

    init:function(element, valueAccessor, allBindingsAcessor, viewModel, bindingContext){

        var fnReference = valueAccessor();           
        var childBindingContext = bindingContext.createChildContext(fnReference);
        ko.applyBindingsToDescendants(childBindingContext, element);

        $(element).myplugin();

        return {'controlsDescendantBindings':true};        
    },
};

That will cause your LIs to render properly.

Upvotes: 1

Related Questions