Kal_Torak
Kal_Torak

Reputation: 2551

Pass multiple values/observables to custom binding

I'm doing a simple custom binding which accepts a plain observable and adds the value of the observable to the bound element's css class list, like so:

<div class="container" data-bind="cssClassBinding: state">
</div>

ko.bindingHandlers.cssClassBinding = {//simplified example code
    init: function (element, valueAccessor) {
        $(element).addClass(ko.utils.unwrapObservable(value));
    },
}

What I'm trying to do is be able to bind multiple values with this binding. I tried just putting another binding with a different value, but KO only evaluates one instance per element apparently.

//won't work
<div class="container" data-bind="cssClassBinding: state, cssClassBinding: type">
</div>

So I'm trying to see if I can do it more like this:

<div class="container" data-bind="cssClassBinding: {state, type}">
</div>

ko.bindingHandlers.cssClassBinding = {//simplified example code
    init: function (element, valueAccessor) {
        foreach (observableValue in iDon'tKnowWhere)
            $(element).addClass(ko.utils.unwrapObservable(observableValue));
    },
}

Any ideas?

Upvotes: 0

Views: 1623

Answers (2)

mcdermott7run
mcdermott7run

Reputation: 56

An alternate way to bind multiple observables is creating an object within the binding:

<div data-bind="exampleBinding: { State: state, Type: type }"></div>

Then the custom binding would access those properties through the valueAccessor (this assumes state and value are knockout observables on the view model):

ko.bindingHandlers.exampleBinding = {
    init: function (element, valueAccessor) {
        var value = valueAccessor();
        // read properties
        console.log(value.State());
        console.log(value.Type());
        // update properties
        value.State('test1');
        value.Type('test2');
    }
}

Upvotes: 3

Kal_Torak
Kal_Torak

Reputation: 2551

Easiest way I found is just to handle the binding an array of observables, like so:

<div class="container" data-bind="cssClassBinding: [state, type]">
</div>

And just write the custom binding to check if it's an array or not.

Upvotes: 1

Related Questions