(我知道标题不是最好的 - 随意编辑它)
我有以下Knockout.js视图模型:
function Bar() {
var self = this;
self.baz = "baz";
}
function Foo() {
var self = this;
self.bars = ko.observableArray([]);
self.addBar = function () { self.bars.push(new Bar()); };
self.removeBar = function (bar) { self.bars.remove(bar); };
}
function ViewModel() {
var self = this;
self.foo = new Foo();
}
ko.applyBindings(new ViewModel());
以下HTML:
<a href="#" data-bind="click: foo.addBar">Add</a>
<ul data-bind="foreach: foo.bars">
<li><span data-bind="text: baz"></span> <a href="#" data-bind="click: $root.foo.removeBar">Remove</a></li>
</ul>
这可以按预期工作。但是,如果我将绝对路径$root.foo.removeBar
更改为$parent.removeBar
,就像这样:
<a href="#" data-bind="click: $parent.removeBar">Remove</a>
项目删除停止工作;但是,我没有在控制台上看到任何错误。
通过一些实验,我发现$parent
在这里引用了可观察数组(Bar
实例)中的当前项,而不是包含对象(a Foo
实例)。
我的问题是:如何在绑定中使用相对引用来引用包含对象?
编辑:我找到了一种方法:
<!-- ko with: foo -->
<ul data-bind="foreach: bars">
<li>
<span data-bind="text: baz"></span>
<a href="#" data-bind="click: $parent.removeBar">Remove</a>
</li>
</ul>
<!-- /ko -->
它不漂亮但它有效。它基本上归结为在foo
之前为foreach
属性打开新范围。
所以我的下一个问题是:有更好的方法吗?
答案 0 :(得分:2)
每次使用控制流绑定(例如'with'或'foreach')(onOptionsItemSelected(android.view.MenuItem)
)时,都会创建Knockout绑定上下文。所以我认为混淆是绑定层次结构是由html决定的,而不是由你的视图模型决定的。在您的视图模型中,层次结构是ViewModel - &gt; Foo - &gt;条形码,但在标记中有$ root是ViewModel,然后创建的下一个上下文是Bars对象,所以它的父对象直接映射到ViewModel,从而跳过了Foo。
至于更好的方式......我实际上并不介意使用With绑定我认为它使得代码更清晰,而不是在每个绑定上深入了解foo。在这种情况下更好的是纯粹的意见。您可以使用$ parent.foo.removeBar而不是$ root.foo.removeBar,因为您知道在您的上下文中那些引用相同的东西。第三种选择是使用Foo本身作为你的根视图模型,因为除了在这个例子中提供Foo之外它似乎没什么用,但是你的实际用例可能更复杂。