Knockout $ root和$ parent中Javascript变量的范围

时间:2013-08-26 21:17:52

标签: javascript mvvm knockout.js typescript

我有一个设置为使用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调用时收到错误。

1 个答案:

答案 0 :(得分:3)

有多种方法可以更改click处理程序的范围。

使用Bind

您可以使用bind javascript method,您可以在调用函数时明确指定this值:

<button data-bind="event: { click: $root.clickMe.bind($root) }" />

clickMethis将是您的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");
  }

然而,这会将clickMeContainer原型移动到实例函数中,因此可能会出现性能问题,但您无需更改数据绑定扩展。

SideNote:Knockout有专门的click binding,因此您可以将data-bind="event: {click: $root.clickMe}"替换为data-bind="click: $root.clickMe"