我有一个设置为使用knockout的javascript viewmodel,我在该viewmodel中有两个viewmodel,我在我的页面上下文中有数据绑定。 所以我设置了我的页面,以便一个viewmodel绑定到我的页面的一部分,带有“with”绑定,然后另一个viewmodel绑定到另一个带有“with”绑定的部分。 现在我设置它,以便在点击事件后页面上的一个项目我绑定到$ root(容器视图模型)并且我想在另一个视图模型上编辑一些observable(不在此部分中我有“带”绑定的页面。在我称之为“root”的方法中,我将其设置为“var self = this”,然后在另一个viewmodel上编辑我需要编辑的属性。问题是,当我在“with”绑定中调用$ root或$ parent作为我想要操作的原始对象(在此实例中为容器或“root”)时,我的方法是更改方法的范围作为具有“with”绑定的viewmodel,因此它没有我需要的任何变量或我需要操作的其他视图模型。
有没有办法将我的范围从$ parent或$ root调用更改为我目前获得的其他内容?我只希望范围是容器对象的范围,而不是特定的视图模型。
代码示例(在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调用时收到错误。
答案 0 :(得分:3)
有多种方法可以更改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
更改为“箭头函数”这是一个TypeScript构造,以在函数调用期间保留this
:
clickMe = () => {
var self = this;
console.log(self);
self.viewModelB.property("yes");
}
然而,这会将clickMe
从Container
原型移动到实例函数中,因此可能会出现性能问题,但您无需更改数据绑定扩展。
SideNote:Knockout有专门的click binding,因此您可以将data-bind="event: {click: $root.clickMe}"
替换为data-bind="click: $root.clickMe"
。