这是一个演示我的问题的jsFiddle:http://jsfiddle.net/dDEd5/4/
总之,我有一个简单的ViewModel:
ViewModel = function () {}
ViewModel.prototype = {
child: function () {},
children: new Array(3),
outermethod: function () {
this.innerMethod();
},
innerMethod: function () {
alert("ok!");
},
outerProperty: function () {
return this.innerProperty();
},
innerProperty: function() {
return "Property is OK";
}
}
我正在尝试使用“click”绑定绑定此ViewModel。问题是当我的绑定使用$ parent上下文时,我的ViewModel中的'this'值无法解析为ViewModel。
例如,此绑定可以正常工作:
<div>
<span data-bind="text: outerProperty()"></span>
<button data-bind="click: outermethod">This Works</button>
</div>
然而,当我使用另一个绑定上下文并尝试使用$ parent调用我的ViewModel时,事情就会崩溃。在以下两个示例中,属性解析正常;但是,按钮都出错:
<div>
<!-- ko with: child -->
<span data-bind="text: $parent.outerProperty()"></span>
<button data-bind="click: $parent.outermethod">This Doesn't</button>
<!-- /ko -->
</div>
和
<div>
<!-- ko foreach: children -->
<span data-bind="text: $parent.outerProperty()"></span>
<button data-bind="click: $parent.outermethod">These Don't Either</button>
<!-- /ko -->
</div>
我已经完成了尽职调查,试图了解执行上下文如何在javascript中工作以及这些示例失败的原因;但是,我对此感到茫然。
答案 0 :(得分:7)
当Knockout执行处理程序时,它使用在该级别绑定的当前数据作为上下文。因此,当使用$parent
或$root
之类的内容时,这可能会导致问题。
有几种方法可以处理它:
- 你可以将它绑定到绑定本身的正确上下文中,如:
`click: $parent.outermethod.bind($parent)`
这将返回一个新功能,确保$parent
为this
。
- 您可以在视图模型中绑定它。由于您将功能放在原型上,因此更具挑战性。
一种技术(不使用原型)是使用变量来跟踪this
的正确值,并在您的函数中引用它,如:
var ViewModel = function() {
var self = this;
this.outermethod = function() {
self.innerMethod();
};
};
使用原型,您仍然可以将实现放在原型上,然后在实际实例上创建绑定版本,如:
var ViewModel = function() {
this.outermethod = this.outermethod.bind(this);
};
因此,这将在实例上创建一个新函数,该函数使用正确的上下文调用原型的函数实现。