我们已经知道在使用Knockout时执行var self = this
很有用,以避免事件处理程序中出现问题。但是,我在Typescript中观察到奇怪的行为。下面是一个简化的代码示例。
<i class="icon-edit" data-bind="click: $parent.GetEditForm"></i>
export class Foo
{
public ID: KnockoutObservable<Number>;
}
export class FooEditor
{
public Items: KnockoutObservableArray<Foo>;
public GetEditForm(item: Foo, event)
{
console.log(this);
console.log(item);
}
}
根据Visual Studio,this
是FooEditor
的实例,item
是Foo
的实例。但是,在执行期间,this
和item
都会引用Foo
的实例。 TypeScript在这里错了吗?或者这是Knockout神奇的一部分吗?
答案 0 :(得分:2)
您可以使用箭头函数保留TypeScript中的当前词汇上下文,例如:
class Example {
private name = 'Example';
constructor() {
window.setTimeout( () => { alert(this.name); }, 1000);
}
}
在此示例中,this.name
将为“示例”,因为我们使用了箭头函数:() =>
。如果您使用普通函数尝试相同操作,则会丢失this
:
class Example {
private name = 'Example';
constructor() {
window.setTimeout( function() { alert(this.name); }, 1000); // undefined
}
}
在引擎盖下,TypeScript引入了一个变量来存储范围并将其替换为函数...
var _this = this;
window.setTimeout(function () {
alert(_this.name);
}, 1000);
答案 1 :(得分:1)
它的javascript如何工作,&#39;这个&#39;与来电者联系在一起。如果你想要这个&#39;这个&#39;做父母试试这个:
<i class="icon-edit" data-bind="click: $parent.GetEditForm.bind($parent,$data)"></i>
bind会绑定这个&#39;在你的情况下,第一个参数是$ parent,然后传递$ data(foo)作为第一个参数。
答案 2 :(得分:0)
我遇到了同样的问题,在回调函数中失去了范围。
我尝试了箭头功能,但仍然无法保持范围。
所以,在挖掘之后我得到了这个解决方案:
loadObject = () => {
var mySelf = this;
Phoria.Util.importGeometryWavefront({
url: "app/js/models/phoria/teapot.obj",
scaleTo: 5,
fnSuccess: function (args) { mySelf.placeObject(mySelf,args) },
reorder: false,
center: true
});
}
placeObject = (mySelf,obj) =>{
mySelf.entityTeapot= Phoria.Entity.create({
points: obj.points,
polygons: obj.polygons,
style: {
specular: 0,
drawmode: "solid",
shademode: "lightsource", //gouraud
fillmode: "inflate"
}
});
mySelf.scene.graph.push(this.entityTeapot);
};
我跟随了这个答案的引导Typescript + Jquery Ajax + this
但我在使用“自我”时遇到了一些问题(它指向Window)。
最后,它似乎正在拦截回调调用并将范围注入其中。
希望它有所帮助, 雷纳托