3

这是一个 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";
    }
}

我正在尝试使用“单击”绑定来绑定此 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 中的工作方式以及这些示例失败的原因;但是,我对此不知所措。

4

1 回答 1

7

当 Knockout 执行处理程序时,它使用在该级别绑定的当前数据作为上下文。因此,当使用类似$parentor时$root,这可能会导致问题。

有几种处理方法:

-您可以将其绑定到绑定本身中的正确上下文,例如:

`click: $parent.outermethod.bind($parent)`

这将返回一个确保$parentwill be的新函数this

- 你可以在你的视图模型中绑定它。由于您将功能放置在原型上,因此更具挑战性。

一种技术(不使用原型)是使用变量来跟踪正确的值this并在函数中引用它,例如:

var ViewModel = function() {
  var self = this;

  this.outermethod = function() {
     self.innerMethod();
  };

};

使用原型,您仍然可以将实现放在原型上,然后在实际实例上创建绑定版本,例如:

var ViewModel = function() {
   this.outermethod = this.outermethod.bind(this);
};

So, this will create a new function on the instance that call the prototype's implementation of the function with the correct context.

于 2013-01-18T03:29:58.997 回答