我有一个设置为使用 knockout 的 javascript viewmodel,我在该 viewmodel 中有两个 viewmodel,我在页面上下文中对其进行了数据绑定(bind)。 所以我设置了我的页面,以便一个 View 模型通过“with”绑定(bind)绑定(bind)到我页面的一部分,然后另一个 View 模型通过“with”绑定(bind)绑定(bind)到另一个部分。 现在我已经设置好它以便在单击事件后页面上的一个项目我绑定(bind)到 $root (容器 View 模型)并且我想在另一个 View 模型上编辑一些可观察对象(不在本节的这一部分)我有“with”绑定(bind)的页面)。在我调用的“root”方法中,我将其设置为“var self = this”,然后编辑我需要在另一个 View 模型上编辑的属性。问题是,当我在“with”绑定(bind)中调用 $root 或 $parent 时,方法的范围从我想要操作的原始对象(容器或本例中的“root”)更改为作为具有“with”绑定(bind)的 View 模型,因此它没有我需要的任何变量或我需要操作的其他 View 模型。
有没有办法将我的范围从 $parent 或 $root 调用中更改为我当前获得的范围以外的范围?我只希望范围是容器对象的范围,而不是特定的 View 模型。
代码示例(在 TypeScript 中):
class Container
{
viewModelA = new ViewModel();
viewModelB = new ViewModelB();
clickMe(){
var self = this;
console.log(self);
self.viewModelB.property("yes");
}
}
<span data-bind="with: viewModelA"> <button data-bind="event: {click: $root.clickMe}" /></span>
console.log 将输出 viewModelA,我会在调用 self.viewModelB 时收到错误消息。
最佳答案
有多种方法可以改变 click
的范围处理程序。
使用Bind
您可以使用 bind
javascript method , 这样你就可以明确指定 this
应该是什么函数被调用时的值:
<button data-bind="event: { click: $root.clickMe.bind($root) }" />
在你的clickMe
this
将是你的Container
通过 $root
作为参数
<button data-bind="event: { click: function() { $root.clickMe($root) } }" />
你需要改变你的clickMe
到:
clickMe(container){
var self = container;
console.log(self);
self.viewModelB.property("yes");
}
使用“箭头函数”
或者您可以更改您的 clickMe
对于“箭头函数”,这是一个保留 this
的 TypeScript 结构在函数调用期间:
clickMe = () => {
var self = this;
console.log(self);
self.viewModelB.property("yes");
}
但是这会移动 clickMe
来自 Container
将原型(prototype)转换为实例函数,因此它可能会出现性能问题,但您无需更改数据绑定(bind)表达式。
旁注:Knockout 有一个专用的 click binding这样你就可以替换 data-bind="event: {click: $root.clickMe}"
与 data-bind="click: $root.clickMe"
.
关于javascript - Knockout $root 和 $parent 中 Javascript 变量的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18453178/