Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I create a custom binding that uses other bindings in knockout.js

I have a custom binding for translations:

ko.bindingHandlers.lang = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        this.lang = [
            'text1':'text1 translated'
            ,'text2':'text2 translated'
        ];
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var keyword = valueAccessor();
        var translatedString = this.lang[keyword];
        $(element).text(translatedString );
    }
};

Which I use like this:

<span data-bind="lang:'text1'"></span>

However, I also have a binding for creating a table row formating:

ko.bindingHandlers.tableRow = {
    update : function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        $(element).html("<td>" + valueAccessor()[0] + "</td><td>" + valueAccessor()[1] + "</td>");
    }
}

Which I use like this:

<tr data-bind="tableRow:['text1','text2']"></tr>

To the question:

Now I would like to combine these bindings so I could call my tableRow binding like this:

<tr data-bind="tableRow:[lang:'text1','text2']"></tr>

The code above is ofcourse only for example, in reality there's more going on in these bindings.

I have read through the documentation multiple times and spent a long time searching for a solution but couldn't find anything. Maybe because this can't be done?

like image 417
Joche Avatar asked Feb 13 '13 09:02

Joche


People also ask

What are the types of binding supported by Knockout JS?

Binding Values The binding value can be a single value, literal, a variable or can be a JavaScript expression.

What is two way binding in Knockout JS?

KO is able to create a two-way binding if you use value to link a form element to an Observable property, so that the changes between them are exchanged among them. If you refer a simple property on ViewModel, KO will set the form element's initial state to property value.

What is $data in Knockout?

The $data variable is a built-in variable used to refer to the current object being bound. In the example this is the one of the elements in the viewModel.

How do you bind a function in Knockout JS?

The function you want to bind to the element's click event. You can reference any JavaScript function - it doesn't have to be a function on your view model. You can reference a function on any object by writing click: someObject. someFunction .


1 Answers

All you need to do is relay or modify the values from one bindingHandler to the other ones you want to activate.

So, in your tablerow handler, call init and update (in their respective functions):

ko.bindingHandlers.lang.init(element, valueAccessor, allBindingsAccessor, viewModel)

Modify the parameters as needed of course. It's likely you'll grab one of the values from your array and pass it as the second parameter to init and update.

This is a great way to activate other standard built in bindings as well.

Update: Adding the comment from @Joche just to make this more readable:

var value = valueAccessor(); 
var newValueAccessor = function() {
    return translatedString; }; 
ko.bindingHandlers.lang.init(element, newValueAccessor,
       allBindingsAccessor, viewModel);
like image 123
WiredPrairie Avatar answered Sep 25 '22 12:09

WiredPrairie