Reputation: 9065
I'd like to make a custom bindingHandler, something like data-bind="withSmartForm: formModel"
.
But despite all the other functionality I want it to behave like with
, so the current context changes to formModel, and I can access the subproperties like data-bind="value: email"
.
I know there are workarounds like always prefixing the subproperties with formModel, or put a with: formModel
in a parent element, but as I will be using this pattern a lot I'd like to keep it as short as possible.
In the following fiddle I'd like to merge the with
and withSmartForm
into one bindingHandler.
Any ideas? Thanks!
Update: working example
http://jsfiddle.net/k89Fg/4/ - thanks to Andrew Walters for the winning answer!
Upvotes: 1
Views: 1141
Reputation: 4803
This is described in the docs here: http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html
From the docs: Bindings such as with and foreach create extra levels in the binding context hierarchy. This means that their descendants can access data at outer levels by using $parent, $parents, $root, or $parentContext. If you want to do this in custom bindings, then instead of using bindingContext.extend(), use bindingContext.createChildContext(someData).
Example:
ko.bindingHandlers.withProperties = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// Make a modified binding context, with a extra properties, and apply it to descendant elements
var newProperties = valueAccessor(),
childBindingContext = bindingContext.createChildContext(viewModel);
ko.utils.extend(childBindingContext, newProperties);
ko.applyBindingsToDescendants(childBindingContext, element);
// Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice
return { controlsDescendantBindings: true };
}
};
Upvotes: 7