在Typescript中对子进行范围限定的问题

时间:2013-04-10 12:13:48

标签: javascript knockout.js this typescript scoping

这是 ALMOST 与我到目前为止所读到的每个其他this范围问题相同,而不是一个微小的差异,这使得它(imo)提出这个问题。

现在最初我的问题是使用Knockout和Typescript确定this的范围,所以给出以下内容:

class ViewModel
{
    public SomeObservableArray = new ko.observableArray();

    public AddToTheObservableArray(someJsonData: any) 
    {
        this.SomeObservableArray.push(new SomePojo(someJsonData));
    }
}

因此上面代码中的this位会爆炸,因为Typescript会让你认为this是类实例,但实际上它是由于ajax回调或视图元素而导致的其他因素,无论覆盖this关键字的情况如何。

所以要解决这个问题,大多数解决方案是将代码移动到类的构造函数中,我个人觉得这很糟糕,但是考虑到使用TypeScript带来的其他好处,这个小小的恐怖是可以接受的。所以我们都在同一页面上,下面的代码修复了上述问题:

class ViewModel
{
    public SomeObservableArray = new ko.observableArray();
    public AddToTheObservableArray = (someJsonData: any) => Void;

    constructor
    {
        this.AddToTheObservableArray = (someJsonData: any) => {
            this.SomeObservableArray.push(new SomePojo(someJsonData));
        };
    }
}

我只是把这个示例代码写在我的头顶,所以我为任何错别字等道歉,但它是所面临的常见问题和常见解决方案/解决方法。

现在!我的问题是下一步,我有这样的代码:

class ViewModel
{
    public SomeObservableArray = new ko.observableArray();
    public AddToTheObservableArray = (someJsonData: any) => Void;


    constructor
    {
        this.PopulateObservableArray = (someJsonArrayData: any) => {
            this.SomeObservableArray.removeAll();
            someJsonArrayData.forEach(function(someJsonData) {
                this.SomeObservableArray.push(new SomePojo(someJsonData));
            });
        };
    }
}

输出的代码如下所示:

var ViewModel = (function(){
    function ViewModel(){
        var _this = this;

        this.SomeObservableArray = new ko.observableArray();

        this.AddMultipleEntitiesToObservableArray = function(someJsonArrayData) {
            _this.SomeObservableArray.removeAll();
            someJsonArrayData.forEach(function(someJsonData) {
                this.SomeObservableArray.push(new SomePojo(someJsonData));
            });
        }
    };
    return ViewModel;
})();

我再次为任何拼写错误道歉,因为我只是简化了较大的项目输出,但是这里要看的主要内容是forEach方法子this仍然存在,因此我收到错误this.SomeObservableArray is undefined

我确信一个可能的解决方案是将foreach提取出来并使其成为自己的方法,然而这就像在blutack上粘贴cellotape一样,所以我想知道是否有一些更优雅的解决方案或我的一些不道德行为可以改为至少不要让它更难以理解。

1 个答案:

答案 0 :(得分:6)

是的,实际上非常简单。只需在任何方法上使用lambda表达式,并将其范围限定为更高函数的范围。在您的情况下,您需要将您的示例重写为:

class ViewModel
{
    public SomeObservableArray = new ko.observableArray();
    public AddToTheObservableArray = (someJsonData: any) => Void;


    constructor()
    {
        this.PopulateObservableArray = (someJsonArrayData: any) => {
            this.SomeObservableArray.removeAll();
            someJsonArrayData.forEach((someJsonData) => {
                this.SomeObservableArray.push(new SomePojo(someJsonData));
            });
        };
    }
}

PS:最佳做法是不在每个操作中操纵一个可观察数组,因为每次更改都会通知该数组的订阅者。只需将数据推送到临时数组,然后将此数组设置为可观察数组的值(仅限我的2个。)