I'm using Knockout.js to wire up a dynamic form display. So instead of lovely named properties, I have an arbitrary number of "fields" in an array that I need to display and wire up. I think I'm close, but am failing in putting the finishing touches on my custom binding.
The Data
myDynamicFields = [
{
name: "email",
value: "me@gmailllllll.com",
type: "text",
validation: {required: true},
label: "Email Address",
},
{
name: "username",
value: "bobsmith",
type: "text",
validation: {required: true},
label: "Username"
}
];
I'm using ko.mapping to map this array to an observable array of observables. So not only is the entire array an observable, but each field such as "name" and "value" are also observables. This array should be able to have any number of elements and is keyed on "name".
My Custom Binding
The reason I need a custom binding (I think) is so that when something changes in my view, I can wire up which member of the array has changed. Again, it's keyed on name so I do a quick lookup. Check it:
ko.bindingHandlers.specialValue = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
model = _.find(viewModel, function (guy){
return guy.name()==valueAccessor();
});
ko.bindingHandlers.value.init(element, model.value, allBindings, viewModel, bindingContext);
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
model = _.find(viewModel, function (guy){
return guy.name()==valueAccessor();
})
ko.bindingHandlers.value.update(element, model.value, allBindings, viewModel, bindingContext);
}
};
My Template
(Simply iterates through each element of my array)
{{#.}}
<p>{{label}}: <input data-bind='specialValue: "{{name}}", valueUpdate: "afterkeydown"'/></p>
{{/.}}
However, when I do this, nothing updates. I've gone deep into the Knockout code and found that a property called _ko_property_writers
is not present on the allBindingsObject
, but I'm out of my league as far as understanding of Knockout at this point.