(我知道标题不是最好的 - 请随意编辑)
我有以下 Knockout.js View 模型:
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
实例)中的当前项 ,而不是包含对象(Foo
实例)。
我的问题是:如何在我的绑定(bind)中使用相对引用来引用包含对象?
编辑:我找到了一种可行的方法:
<!-- 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 -->
虽然不漂亮,但很管用。它基本上归结为在 foreach
之前为 foo
属性打开一个新范围。
所以我的下一个问题是:有更好的方法吗?
最佳答案
Knockout 绑定(bind)上下文会在“每次您使用控制流绑定(bind),例如‘with’或‘foreach’”时创建(reference)。所以我认为混淆是绑定(bind)层次结构是由 html 而不是你的 View 模型决定的。在您的 View 模型中,层次结构是 ViewModel -> Foo -> Bars,但在标记中有 $root 是 ViewModel,然后创建的下一个上下文是为 Bars 对象创建的,因此它的父级直接映射到 ViewModel跳过 Foo。
至于更好的方法......我实际上不介意您拥有的 With 绑定(bind),我认为它使代码更清晰,而不是在每次绑定(bind)时都必须深入到 foo。在这种情况下更好的纯粹是意见。您可以交替使用 $parent.foo.removeBar 而不是 $root.foo.removeBar 知道在您的上下文中它们指的是同一件事。第三种选择是使用 Foo 本身作为您的 Root View 模型,因为在此示例中它除了提供 Foo 之外似乎没有做太多其他事情,但您的实际用例可能更复杂。
关于javascript - Knockout.js - $parent 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41876394/