代码中的“this”在执行期间与“this”不匹配

时间:2013-07-09 08:21:19

标签: knockout.js typescript

我们已经知道在使用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,thisFooEditor的实例,itemFoo的实例。但是,在执行期间,thisitem都会引用Foo的实例。 TypeScript在这里错了吗?或者这是Knockout神奇的一部分吗?

3 个答案:

答案 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)。

最后,它似乎正在拦截回调调用并将范围注入其中。

希望它有所帮助, 雷纳托