【问题标题】:When $parent.foo is a prototype method, the this is not the parent, workaround?当 $parent.foo 是原型方法时, this 不是父方法,解决方法?
【发布时间】:2013-06-12 19:33:43
【问题描述】:

在我的视图模型中,我有原型方法,其中 this 上下文是 for each 中的项目,而不是实际的视图模型。我如何做到这一点?

  <button data-bind="click: $parent.methodThatNeedsAccesToTheParentViewModel">Edit</button>

视图模型:

ViewModel.prototype.methodThatNeedsAccesToTheParentViewModel= function () {
        this = duff //this is the item in the foreach, not the real parent
    };

想法?

【问题讨论】:

  • 您是否在问如何在您的方法中实际获取 this 变量以指向您的 ViewModel 实例?还是别的什么?

标签: knockout.js


【解决方案1】:

不要将函数直接传递给点击绑定,将其包装在一个匿名函数中以便在视图模型的上下文中调用它:

<button data-bind="click: function() { $parent.methodThatNeedsAccesToTheParentViewModel() }">Edit</button>

这样,当绑定被激活时,它将使用 $parent 作为调用的上下文 - 即 this

值得注意的是(因为我们看不到文件绑定的结构)$parent 变量将引用当前项目之前的 binding迭代,它不一定是对象图中项目的父项。

编辑:我在上面遗漏了一些括号...

编辑 2:由于绑定的解析方式,此方法有效。当通过敲除应用绑定时,表达式被解析并且必须评估为 function (因此当您直接绑定到函数时不需要括号)。然后当点击绑定被激活时调用这个函数。

但这里有一个问题,因为原型 javascript 中的 this 关键字不受函数所有者的约束(即在哪里定义),而是在调用它的方式上(如解释在mozilla documentation 中更好)在这种情况下敲除调用函数不是通过拥有它的对象(这将正确绑定 this 运算符),而是将其显式绑定到其当前绑定上下文(因为它不能可能知道该函数最初是哪个实例)。您可以通过获取对您的函数的引用,然后在调用时将其绑定到另一个对象来复制此行为 - 一个示例:

A = function() {
   this.name = "foo";
};
A.prototype.getName = function() { return this.name; };

a = new A();

console.log(a.getName()); // should log "foo" as expected

f = a.getName; // now f contains a reference to the function

console.log(f()); // this call the function in the current scope - most likely the window, and return nothing

b = new Object(); // another generic object - suppose this is knockout binding context

console.log(f.call(b)); // this bind the call explicitly to b, but since b has no name property,  nothing is returned again

console.log(f.call(a)); // this time we bind the function call to an object that has a name proerty, so the correct value is returned

另一方面,通过创建一个匿名函数,您在所需对象 ($parent) 的范围内显式地 调用您的方法,因此 this 被正确绑定.

希望对你有所帮助... :)

【讨论】:

  • AFAIK $parent 是 foreach 绑定中的当前项目,所以我希望它有效。有时我想知道在遇到这些问题时使用原型有什么意义。您能否指出解释 function() { ... 如何给出正确上下文的来源?
  • 是的,我一骑上自行车回家,就想这样做!
  • 我没有看到太多关于这种形式的明确文档应用于对象,但它主要可以从click binding documentation 中推断出来,其中匿名函数与函数一起使用。
  • @FutuToad 我在回答中添加了一些 cmets,说明为什么它会这样工作
【解决方案2】:

我遇到了同样的问题,我是这样解决的:

<button data-bind="click: $parent.methodThatNeedsAccesToTheParentViewModel.bind($parent)">Edit</button>

【讨论】:

  • 我也喜欢这种语法,我不喜欢在我的视图中看到function() {...} 的东西。
【解决方案3】:

您的数据绑定中有 $parent,因此应该调用父级上的方法。您的意思是将 $data.methodThatNeedsAccesToTheParentViewModel 作为数据绑定吗?如果你这样做了,那么你需要研究某种 pubsub 框架,knockout postboxjquery pubsub plugin

【讨论】:

  • 因为该方法是一个原型,所以“this”值不是实例化的视图模型(在非原型方法中通常 = $parent),而是 for each 中的孩子,我不想要.
猜你喜欢
  • 2012-08-29
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 2020-07-01
  • 1970-01-01
  • 2011-08-13
相关资源
最近更新 更多