Knockout custom binding descendant $data works only when the property already exists

时间:2016-07-11 21:08:48

标签: knockout.js

everyone. I was reading Knockout js doc here, which relates to controling the descendant bindings. The scenario is that I bind the descendant element with the current binding context using applyBindingsToDescendants, and then I try to access a property in that binding context in the descendant element using $data.property_name, it only works when the property_name is already in the original binding_context, if it's added later, then $data.property_name won't work, but it will work if I remove $data, please take a look at this jsfiddle example. Can anyone tell me why it behaves like that?

html

<div data-bind="addBindingProperties: {addedProp: 'ADDED PROPERTY'}">
    <div>Existing property accessible via $data: <span data-bind="text:   $data.existingProp"></span></div>
    <div>Added property not accessible via $data: <span data-bind="text: $data.addedProp"></span></div>
    <div>Added property accessible by removing $data: <span data-bind="text: addedProp"></span></div>
</div>

javascript

ko.bindingHandlers.addBindingProperties = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.utils.extend(bindingContext, valueAccessor());
        ko.applyBindingsToDescendants(bindingContext, element);
        return {controlsDescendantBindings: true};
    }
};

ko.applyBindings({
    existingProp: 'EXISTING PROPERTY'
});

result

Existing property accessible via $data: EXISTING PROPERTY
Added property not accessible via $data:
Added property accessible by removing $data: ADDED PROPERTY

1 个答案:

答案 0 :(得分:1)

此处的$data暗示您的根视图模型,因此这部分是错误的ko.utils.extend(bindingContext, valueAccessor());,因为您实际上只是将其扩展到当前上下文,因此它不会附加到$data

您可以将其扩展到根上下文,以使该属性存在于$data中,如:

ko.utils.extend(bindingContext, valueAccessor());
ko.utils.extend(bindingContext.$root, valueAccessor());