3

这与我迄今为止读过的所有其他范围界定问题几乎相同,除了一个细微的差异,这使得提出这个问题具有相关性(imo this

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

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 上粘贴纤维胶带,所以我想知道是否有一些更优雅的解决方案或我的一些错误行为可以改变至少不必让它更难读。

4

1 回答 1

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:最好不要在 a for each 中操作可观察数组,因为每次更改都会通知该数组的订阅者。只需将您的数据推送到一个临时数组,然后将此数组设置为您的可观察数组的值(只是我的 2cts。)

于 2013-04-10T12:32:40.573 回答