问题 来自绑定的Knockout 2.0参数的顺序不正确?


使用Knockout 2.0使用此数据绑定:

data-bind="click: $root.deleteSomeEntity.bind($data, $parent)"

在Knockout viewmodel JavaScript中的第一个参数

self.deleteSomeEntity = function (data, parent) {
    // perform deletion
}

似乎是父母而不是数据。

是否有这种行为的原因或我遗漏的东西?


1210
2018-02-16 14:02


起源



答案:


你打电话时 bind 第一个参数将是值 this。所以,在你的电话中 this 将会 $data 第一个参数将是 $parent

如果 $root 是 $parent 在这种情况下,你可以这样做:

$root.deleteSomeEntity.bind($root)

KO将数据作为第一个参数传递 this 将被设置为 $root

如果 $parent 不是 $root (而且你可能不想依赖 this 是一个不同的对象 $root 在你的root方法中,然后你会做类似的事情:

$root.deleteSomeEntity.bind($root, $data, $parent) 

否则,肯定有办法确保你有正确的 this 在您的视图模型中。这取决于你的结构。


12
2018-02-16 14:12



按照你的建议: jsfiddle.net/6MmWs/5 但是当点击删除和 self.deleteContactPhone = function(viewModel, phone, contact) viewModel是手机,手机是联系人,联系人也是手机。 this 目前是viewmodel。 - kendaleiv
你会希望它更像: jsfiddle.net/rniemeyer/6MmWs/6。有几件事要提。 remove 是observableArray上可用的函数。我换了你的 phones 数组是可观察的,所以你有 remove 并在删除一个UI时更新UI。 - RP Niemeyer
另一件事是想要你的功能签名 function(phone, contact)。第一个参数 bind 是目标,用于控制值 this 当你的功能运行。所以,它实际上并不是函数的参数。 - RP Niemeyer
感谢ryan的这个信息,我不确定我是否真的同意KO使用第一个论点神奇地成为 this 但这是你们的决定。但是,这个文档完全不清楚。我强烈建议您更新文档 knockoutjs.com/documentation/click-binding.html 包括我们在这里讨论的主题。我回过头来看看这个,我发现的唯一一个关于这个的参考是“这被重新定义为在事件处理程序中的其他东西”,我甚至不确定是否直接匹配我们的主题或者是否是一般的javascript - Chris Marisic
请注意:使用第一个参数不是KO的决定 bind 如 this。 bind 大多数较新的浏览器本身都支持KO,KO为没有它的浏览器添加了这种支持。有关绑定的一些信息: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/... - RP Niemeyer


答案:


你打电话时 bind 第一个参数将是值 this。所以,在你的电话中 this 将会 $data 第一个参数将是 $parent

如果 $root 是 $parent 在这种情况下,你可以这样做:

$root.deleteSomeEntity.bind($root)

KO将数据作为第一个参数传递 this 将被设置为 $root

如果 $parent 不是 $root (而且你可能不想依赖 this 是一个不同的对象 $root 在你的root方法中,然后你会做类似的事情:

$root.deleteSomeEntity.bind($root, $data, $parent) 

否则,肯定有办法确保你有正确的 this 在您的视图模型中。这取决于你的结构。


12
2018-02-16 14:12



按照你的建议: jsfiddle.net/6MmWs/5 但是当点击删除和 self.deleteContactPhone = function(viewModel, phone, contact) viewModel是手机,手机是联系人,联系人也是手机。 this 目前是viewmodel。 - kendaleiv
你会希望它更像: jsfiddle.net/rniemeyer/6MmWs/6。有几件事要提。 remove 是observableArray上可用的函数。我换了你的 phones 数组是可观察的,所以你有 remove 并在删除一个UI时更新UI。 - RP Niemeyer
另一件事是想要你的功能签名 function(phone, contact)。第一个参数 bind 是目标,用于控制值 this 当你的功能运行。所以,它实际上并不是函数的参数。 - RP Niemeyer
感谢ryan的这个信息,我不确定我是否真的同意KO使用第一个论点神奇地成为 this 但这是你们的决定。但是,这个文档完全不清楚。我强烈建议您更新文档 knockoutjs.com/documentation/click-binding.html 包括我们在这里讨论的主题。我回过头来看看这个,我发现的唯一一个关于这个的参考是“这被重新定义为在事件处理程序中的其他东西”,我甚至不确定是否直接匹配我们的主题或者是否是一般的javascript - Chris Marisic
请注意:使用第一个参数不是KO的决定 bind 如 this。 bind 大多数较新的浏览器本身都支持KO,KO为没有它的浏览器添加了这种支持。有关绑定的一些信息: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/... - RP Niemeyer


你为什么用 bind()?默认情况下,如果您只是将javascript函数的名称写为Knockout将通过的单击事件 $data 作为第一个参数,事件作为第二个参数。

http://knockoutjs.com/documentation/click-binding.html (注1和2)

为什么要打扰 bind() 当你可以简单地这样做:

data-bind="click: function() {$root.deleteSomeEntity($data, $parent)}"

2
2018-02-16 15:17



该代码似乎是在没有点击我的情况下执行的。它在data-bind =“foreach:...”里面,如果它改变了什么。 - kendaleiv
哦,当然可以!对不起,我已经编辑了代码 function() 缠绕在点击装订上。这应该按预期工作。 - soniiic
这只是一种风格。很多人不喜欢在他们的标记中加入匿名函数。这是在KO开始时让人们失望的事情之一,特别是当他们习惯于更加不引人注目的方法时。它可以正常工作,虽然我更喜欢确保 this 在视图模型中适当设置。 - RP Niemeyer
@RPNiemeyer:我不喜欢在我的标记中添加匿名函数,但是设置 this 正确的 .bind() 语法绊倒了我,所以soniic的方式结束了 只要 对我有用的方式。因人而异 - Jim G.
@JimG。如果你有一个具体的例子,那么我可以帮助解决它。通常应该有一种方法可以在不使用匿名函数的情况下使其工作。 - RP Niemeyer