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

Gro*_*fit 3 javascript this scoping knockout.js typescript

这与我到目前为止所读到的每个其他范围问题几乎相同,this除了一个微小的差异,这使得它(imo)提出这个问题是相关的.

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

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

    public AddToTheObservableArray(someJsonData: any) 
    {
        this.SomeObservableArray.push(new SomePojo(someJsonData));
    }
}
Run Code Online (Sandbox Code Playgroud)

所以this在上面的代码位将炸毁因为打字稿让你认为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));
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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));
            });
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

输出的代码如下所示:

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;
})();
Run Code Online (Sandbox Code Playgroud)

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

我相信1个可能的解决方案是提取的foreach出来,使之成为自己的方法,然而,这则感觉像在宝贴贴CELLOTAPE,所以我想知道如果有一些更优雅的解决方案或对我而言有些不法行为这是可以改变的至少不必让它更难以理解.

tho*_*aux 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));
            });
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:最好的做法是不要在每个变量中操纵一个可观察数组,因为每个变化都会通知该数组的用户.只需将数据推送到临时数组,然后将此数组设置为可观察数组的值(仅限我的2个.)

  • 我完全赞同你的PS,就像我要去做的那样.如果你的解决方案能使当前的代码更加优雅,那么先生是我的英雄! (2认同)