Knockout.js - 如何创建类似于'with'的自定义bindingHandler

时间:2013-07-13 12:11:54

标签: javascript knockout.js

我想创建一个自定义的bindingHandler,类似于data-bind="withSmartForm: formModel"

尽管所有其他功能我希望它的行为类似于with,因此当前上下文更改为formModel,我可以访问子属性,如data-bind="value: email"

我知道有一些变通办法,比如总是在子属性前面添加formModel,或者在父元素中添加with: formModel,但是因为我将使用这种模式,所以我希望尽可能地缩短它

在下面的小提琴中,我想将withwithSmartForm合并到一个bindingHandler中。

http://jsfiddle.net/k89Fg/1/

有什么想法吗?谢谢!

更新:工作示例

http://jsfiddle.net/k89Fg/4/ - 感谢Andrew Walters获胜的答案!

1 个答案:

答案 0 :(得分:7)

此处的文档中对此进行了描述:http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html

来自文档: with和foreach等绑定在绑定上下文层次结构中创建了额外的级别。这意味着他们的后代可以使用$ parent,$ parents,$ root或$ parentContext访问外层的数据。 如果要在自定义绑定中执行此操作,则不要使用bindingContext.extend(),而是使用bindingContext.createChildContext(someData)。

示例:

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 };
    }
};