Guy Schaller
Guy Schaller

Reputation: 4700

Getting observable from model by String in Knockout.js

I am writing a custom binding handler in Knockout. I want to to pass a String like: firstName as the valueAccessor, then I want to get the observable firstName from my view model, but how do I get an observable by String?

Here is my code:

ko.bindingHandlers.DefaultOrCustom = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {

        var value = valueAccessor(), allBindings = allBindingsAccessor();
        // value will equal "firstName" at this phase
    } 
}

Upvotes: 1

Views: 3481

Answers (1)

John Earles
John Earles

Reputation: 7194

You can access a JavaScript object as an associative array, using your field name as the key (e.g. object.foo can be represented as object['foo']) . Then, as you are pointing to an observable, you call it as a function to get / set the value.

Assuming you have a binding like this:

data-bind="DefaultOrCustom: 'firstName'"

You can access the observable like this:

ko.bindingHandlers.DefaultOrCustom = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {

    var value = valueAccessor(), allBindings = allBindingsAccessor();

    var oldValue = viewModel[value](); // read from the observable
    viewModel[value]('New Value');     // write to the observable 
}

You can get even more flexible by checking the type of the field. If it is 'function' then treat it is an observable - using the () form, otherwise treat it as a regular field.

ko.bindingHandlers.DefaultOrCustom = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {

    var value = valueAccessor(), allBindings = allBindingsAccessor();
    var oldValue;

    if (typeof(viewModel[value]) == 'function') {
      oldValue = viewModel[value]();   // read from the observable
      viewModel[value]('New Value');   // write to the observable
    } else {
      oldValue = viewModel[value];     // read from the field
      viewModel[value] = 'New Value';  // write to the field
    }
}

FYI: typeof is actually not a function, but I often find using this form makes it clearer what I am typing.

Upvotes: 2

Related Questions