[英]'this' scope in typescript callback function
I cannot understand how 'this' context works in typescript. 我无法理解'this'语境如何在打字稿中起作用。 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
}
}
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. this
上下文在打字稿中与在javascript中一样,因为你实际运行的代码是typescript编译器输出的已编译的javascript。
In javascript you have two ways to deal with this issue: 在javascript中,您有两种方法可以解决此问题:
You are probably passing getAdopterById
as a callback, if that's the case then it will be easy to solve using bind
: 您可能正在将getAdopterById
作为回调传递,如果是这种情况,那么使用bind
将很容易解决:
let myobj = new adopterDetailCtrl(...);
...
someFunction(myobj.getAdopterById.bind(myobj));
You can also modify the reference for the method of the instance in the ctor: 您还可以在ctor中修改实例方法的引用:
(1) (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
}
}
Notice that the method declaration is empty and the implementation is set in the ctor using the arrow function. 请注意,方法声明为空,并且使用箭头函数在ctor中设置实现。
(2) (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
}
}
Here in the ctor you reassign the bound this.getAdopterById.bind(this)
to this.getAdopterById
. 在ctor中你将绑定的this.getAdopterById.bind(this)
重新分配给this.getAdopterById
。
In both of these cases you can freely pass the getAdopterById
method as a callback and not worrying about the scope of this
. 在这两种情况下,您可以自由通过getAdopterById
方法的回调,而不是担心的范围this
。
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: 关于箭头函数的另一个注意事项是这是ES6
一个新功能,如果你没有在编译选项中选择ES6
目标,那么编译器实际上不会使用这种表示法,而是会转换它:
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 way the scope of this
is saved in _this
and in the callback function _this.x
is used instead of this.x
. 这样的范围this
是保存在_this
并在回调函数_this.x
代替this.x
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.