0

我们已经知道在使用 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并且itemFoo. 但是,在执行过程中,两者都this引用itemFoo. TypeScript 错了吗?或者这是 Knockout 魔法的一部分?

4

3 回答 3

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);
于 2013-07-09T10:44:35.067 回答
1

它是 javascript 的工作方式,“this”与调用者有关。如果您希望“this”成为父母,请尝试以下操作:

<i class="icon-edit" data-bind="click: $parent.GetEditForm.bind($parent,$data)"></i>

bind 会将“this”绑定到第一个参数,在您的情况下是 $parent,然后将 $data (foo) 作为第一个参数传递。

于 2013-07-09T08:52:50.353 回答
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

但我在使用“self”时遇到了一些问题(它指向 Window)。

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

希望它有帮助,雷纳托

于 2015-06-17T22:36:20.893 回答