Reputation: 4700
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
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