javascript - Knockout.js - $parent 未按预期工作

标签 javascript knockout.js

(我知道标题不是最好的 - 请随意编辑)

JSFiddle for easy testing

我有以下 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/

相关文章:

javascript - 自定义组件的构造函数中的参数始终未定义

javascript - 使用 Node.js 文件系统运行 80 个文件来查找属性是否比运行一个文件中的条件更聪明?

javascript - 如何在CKEDITOR中动态更改插件设置?

javascript - CSS 类的命名空间/前缀,在 Javascript 和 (S)CSS 之间共享

javascript - 编辑、删除和下拉显示正确的字段 knockout js

javascript - 延迟加载自定义绑定(bind)

javascript - knockout.js - 计算的或可观察的

javascript - MooTools 在方法和内部函数中绑定(bind)/保持类范围

javascript - 网页在除 ps3 以外的所有浏览器上都可以正常工作。在 Ps3 浏览器上,页面不会向下滚动

knockout.js - 无法从 knockout 框架中的输入元素取消绑定(bind)事件