2017-01-20 83 views
1

我遇到了使用ES6类的绑定上下文的问题。ES6类和淘汰赛foreach

这里是一个jsfiddle来解释。

当我在类中声明点击功能就像

class viewModel { 
    constructor() { 
     this.data = ko.observableArray([{ firstName: "phil" }, { firstName: "person" }]); 
     this.selectedPerson = ko.observable("none selected"); 
    } 
    selectUser(data){ 
     console.log(this); 
     this.selectedPerson(data.firstName); 
    } 
} 

我必须提供在标记像这样绑定:<div data-bind="text: firstName, click: $parent.selectUser.bind($parent)">

,但是当我在构造函数中声明点击我不不得不提供上下文。

有人知道为什么吗?

+0

我建议使用https://babeljs.io/docs/plugins/transform-class-properties/。用这个你可以写一个方法作为箭头函数 –

回答

0

淘汰赛的事件绑定(这click罩下使用)做了三两件事:

  • 传递当前绑定上下文的$data
  • 传递事件
  • apply绑定到当前$data事件监听器

Source

这意味着,当你在用户点击,这是发生了什么:

viewModelInstance.selectUser.apply(user, [user, event]); 

如果你想引用this在你的处理器,它知道箭头的功能,原型方法之间的差异“是非常重要的未绑定”属性的功能:

this.doSomething = function() { /* ... */ }; 
this.doSomething =() => { /* ... */ }; 

MyClass.prototype.doSomething = function() { /* ... */ }; 

当你写:

this.selectUser = (data) => { /* ... */ }; 

你基本上做到:

this.selectUser = function(data) { /* ... */ }.bind(this); 

这意味着viewModel实例被“固定” /绑定的方法。在构造函数之外定义它使其成为一种原型方法,可以通过其他代码绑定到任何this上下文。

搜索“es6箭头功能”和this可以找到更多关于如何工作的答案。例如:When should I use Arrow functions in ECMAScript 6?

+0

所以为了避免必须调用.bind($ parent/$/root)我可以在构造函数中声明它使“this”正确绑定?我虽然想避免构造函数中的逻辑,还是仅适用于类型化语言? –

+0

在构造函数中定义它有其缺点(如:每个实例重新定义该方法),但它将起作用。或者,您可以在每个用户中包含对选择模型的引用,并让他们拥有自己的“select”方法(我的个人偏好)。第三种选择是使用[“邮箱模式”](https://github.com/rniemeyer/knockout-postbox)在模型之间进行通信。 (看起来像这个直截了当的例子矫枉过正) – user3297291

+0

我也喜欢第二个(如果我们在同一页上,所以https:// jsfiddle。net/mbr4mjtp/1/for ref),但是如何处理来自服务器的动态数据呢?我们需要遍历每一个并添加一个选择函数。或使用映射实用程序。还是我完全错过了这个标记? –