这比听起来要简单得多。
想象一下,我有一个自定义绑定:
KO.bindingHandlers.custom = {
init:function(element, valueAccessor, allBindingsAccessor,
context, bindingContext) {
...
}
});
通过HTML标记应用,如下所示:
<div>
<div data-bind="with: a">
<span data-bind="custom: aa"></span>
</div>
<div data-bind="with: b">
<span data-bind="custom: bb"></span>
</div>
</div>
其中ViewModel结构为:
{
root: {
a: {
aa: 100
},
b: {
bb: 200
}
}
}
我想知道,在init
函数中谁是“爸爸”,可以这么说,以便当init
正在处理custom: bb
绑定时,我想知道属性路径是root.b
(或得到任何合适的指示)。
显然,使用bindingContext.$parent
并没有帮助,因为它也包含a
。
尝试
到目前为止,最接近的是使用bindingContext.createChildContext
并在绑定中传递父属性的名称(如下面的第一个custom
绑定):
<div>
<div data-bind="with: a">
<span data-bind="custom: {name: 'aa', parent: 'a'}"></span>
</div>
<div data-bind="with: b">
<span data-bind="custom: bb"></span>
</div>
</div>
相当难看。
注意
请注意,嵌套级别可能会超过1 - 如果在“with
或custom
或if
之前存在嵌套的foreach
绑定(您可以获得图片)
有什么想法吗?
谢谢。
答案 0 :(得分:0)
我还没有真正测试过这个,但你可以从你的自定义绑定调用这样的函数来走向绑定上下文堆栈并使用===
来确定父对象中的哪个属性与对象匹配当前的上下文受到约束。
var getPath = function (bindingContext) {
var parts = [],
prev = bindingContext,
i, n;
for (i = 0, n = bindingContext.$parents.length; i < n; ++i) {
var p = bindingContext.$parents[i];
// find which property of p.$data corresponds to prev.$data
var properties = Object.keys(p.$data);
var matchingProperty = ko.utils.arrayFirst(properties, function (name) {
return ko.unwrap(p.$data[name]) === prev.$data;
});
parts.unshift(matchingProperty || "could not determine this part");
prev = p;
}
return parts.join(".");
};
我认为它只适用于简单的with
表达式。复合with
表达式将击败此算法。