'this'scopes中的typescript回调函数 [英] 'this' scope in typescript callback function

查看:124
本文介绍了'this'scopes中的typescript回调函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白这个上下文在打字稿中是如何工作的。我无法在方法中访问类成员。下面是我的代码

I cannot understand how 'this' context works in typescript. I cannot access class members in methods. Below is my code

class adopterDetailCtrl {
    public adopter: IAdopter;
    public $router: any;

    static $inject = ['app.common.services.AdopterService'];
    constructor(private adopterService: app.common.services.IAdopterServices) {
        this.adopter = null;
    }

    $routerOnActivate(next) {
        if (next.params.id > 0) {
            this.getAdopterById(next.params.id);
        }
    }

    getAdopterById(adopterId: number): void {
        var AdopterList = this.adopterService.getAdopterById();
        AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => {
            this.adopter = data[0];//this.adopter is undefined here. this refers to 'window'
        });
    }

    setAdopter(data: IAdopter) {
        this.adopter = data;//can access this.adopter
    }
}


推荐答案

this 上下文在JavaScript中是一样的,因为你实际运行的代码是typescript编译器输出的编译JavaScript。

The this context is just the same in typescript as it as in javascript, as the code you actually run is the compiled javascript that the typescript compiler outputs.

在javascript中,你有两个处理此问题的方法:

In javascript you have two ways to deal with this issue:


  1. 使用 arrow函数

  2. 使用 Function.prototype.bind function

  1. Use the arrow function
  2. Use the Function.prototype.bind function

你可能传递 getAdopterById 作为回调,如果是这样,那么很容易使用 bind

You are probably passing getAdopterById as a callback, if that's the case then it will be easy to solve using bind:

let myobj = new adopterDetailCtrl(...);

...

someFunction(myobj.getAdopterById.bind(myobj));

您还可以修改ctor中实例方法的引用:

You can also modify the reference for the method of the instance in the ctor:

(1)

class adopterDetailCtrl {
    public adopter: IAdopter;
    public $router: any;

    static $inject = ['app.common.services.AdopterService'];
    constructor(private adopterService: app.common.services.IAdopterServices) {
        this.adopter = null;

        this.getAdopterById = (adopterId: number) => {
            var AdopterList = this.adopterService.getAdopterById();
            AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => {
                this.adopter = data[0];//this.adopter is undefined here. this refers to 'window'
            });
        }
    }

    $routerOnActivate(next) {
        if (next.params.id > 0) {
            this.getAdopterById(next.params.id);
        }
    }

    getAdopterById: (adopterId: number) => void;

    setAdopter(data: IAdopter) {
        this.adopter = data;//can access this.adopter
    }
}

请注意,方法声明为空,并使用箭头函数在ctor中设置实现。

Notice that the method declaration is empty and the implementation is set in the ctor using the arrow function.

(2)

class adopterDetailCtrl {
    public adopter: IAdopter;
    public $router: any;

    static $inject = ['app.common.services.AdopterService'];
    constructor(private adopterService: app.common.services.IAdopterServices) {
        this.adopter = null;

        this.getAdopterById = this.getAdopterById.bind(this);
    }

    $routerOnActivate(next) {
        if (next.params.id > 0) {
            this.getAdopterById(next.params.id);
        }
    }

    getAdopterById(adopterId: number): void {
        var AdopterList = this.adopterService.getAdopterById();
        AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => {
            this.adopter = data[0];//this.adopter is undefined here. this refers to 'window'
        });
    }

    setAdopter(data: IAdopter) {
        this.adopter = data;//can access this.adopter
    }
}



this.getAdopterById

在这两种情况下, c $ c> getAdopterById 方法作为回调,而不必担心 this 的范围。

In both of these cases you can freely pass the getAdopterById method as a callback and not worrying about the scope of this.

箭头函数的另一个注意事项是,这是 ES6 中的一个新功能,如果不选择 ES6 target在您的编译选项中,则编译器不会实际上使用这个符号,而是转换为:

Another note on the arrow functions is that this is a new feature in ES6, and if you don't choose the ES6 target in your compilation options then the compiler won't actually use this notation but instead will convert this:

class A {
    private x: number;

    fn(): void {
        setTimeout(() => console.log(this.x), 1);
    }
}

To:

var A = (function () {
    function A() {
    }
    A.prototype.fn = function () {
        var _this = this;
        setTimeout(function () { return console.log(_this.x); }, 1);
    };
    return A;
}());

这样, this 的范围被保存在 _this 中,并使用回调函数 _this.x 而不是 this.x

This way the scope of this is saved in _this and in the callback function _this.x is used instead of this.x.

这篇关于'this'scopes中的typescript回调函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆