Qua*_*ngo 33 lambda knockout.js typescript
我一直在使用TypeScript和KnockoutJS创建一个htmlHelper函数来编辑电子邮件列表.
电子邮件列表是一个叫做电子邮件的Knockout ObservableArray ,我有一个链接,每个项目都要删除它们.这是HTML片段:
<ul data-bind="foreach: emails" >
<li>
<a href="#" data-bind="click: $parent.deleteItem">Delete</a>
<span data-bind="text: $data"></span>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
删除链接绑定到$ parent.deleteItem这是viewmodel中的方法:
// remove item
public deleteItem(emailToDelete: string) {
// remove item from list
this.emails.remove(emailToDelete);
}
Run Code Online (Sandbox Code Playgroud)
这一切都有效,直到执行deleteItem方法.调用此方法时的"this"是数组中的项,而不是视图模型.因此this.emails是一个空引用并失败.
我知道TypeScript支持Lambda语法,但我找不到正确的写入方法(那里有几个例子).
或者我可以采取不同的方法?
Sla*_*wek 48
你可以通过在类构造函数中声明方法体来获得'this'的正确闭包
class VM {
public deleteItem: (emailToDelete: string) => void;
constructor() {
this.deleteItem = (emailToDelete: string) => {
// 'this' will be pointing to 'this' from constructor
// no matter from where this method will be called
this.emails.remove(emailToDelete);
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
似乎从Typescript ver 0.9.1开始,你可以通过使用lambda字段初始化器来实现相同的结果:
class VM {
public deleteItem = (emailToDelete: string) => {
this.emails.remove(emailToDelete);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 24
手套人!只需将$ parent绑定为:
<a href="#" data-bind="click: $parent.deleteItem.bind($parent)">Delete</a>
Run Code Online (Sandbox Code Playgroud)
declare class Email { }
declare class ObservableArray {
remove(any): void;
}
class MyViewModel {
public emails : ObservableArray;
constructor() {
Rebind(this);
}
public deleteItem(emailToDelete: Email) {
this.emails.remove(emailToDelete);
}
}
function Rebind(obj : any)
{
var prototype = <Object>obj.constructor.prototype;
for (var name in prototype) {
if (!obj.hasOwnProperty(name)
&& typeof prototype[name] === "function") {
var method = <Function>prototype[name];
obj[name] = method.bind(obj);
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可能想要一个polyfill Function.bind():
// Polyfill for Function.bind(). Slightly modified version of
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind#Compatibility
if (typeof Function.prototype.bind !== "function") {
Function.prototype.bind = function(oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = <any[]> Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP && oThis ? this: oThis, aArgs.concat());
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
Run Code Online (Sandbox Code Playgroud)
我的最终解决方案是一个基类,它在构造函数上将所有原型函数重新绑定到自身.很像Markus Jarderot的解决方案.
class BaseClass {
constructor() {
for (var i in this) {
if (!this.hasOwnProperty(i) && typeof (this[i]) === 'function' && i != 'constructor') {
this[i] = this[i].bind(this);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
好处:
PS:
你仍然需要绑定polyfill.
我正在使用typesript 0.9.5
| 归档时间: |
|
| 查看次数: |
9293 次 |
| 最近记录: |