访问 'this' 内部承诺
Access 'this' Inside Promise
在下面的打字稿函数中,'this' 没有解析为 EmailValidator 的实例。我如何更正此函数,使其解析为正确的 EmailVaildator 实例,然后我才能访问 _registerServices?
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable(c: AbstractControl): Promise<ValidationResult> {
let q = new Promise((resolve, reject) => {
this._registerServices.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
resolve({ "emailtaken": true })
},
error => {
// Need to communicate the server error? Probably not.
resolve({ "servererror": true })
});
});
return q;
}
}
原来'this'引用是未定义的,即使它被如下使用:
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable(c: AbstractControl): EmailValidator {
return this; // 'This' is undefined!
}
}
我认为这与方法的调用方式有关,可能是在需要静态方法的地方传递了一个非静态方法:
...
this.registerForm = fb.group({
email: ['', Validators.required, this._emailValidator.isAvailableEmail],
password: ['', Validators.compose([Validators.required, Validators.minLength(8)])],
phoneNumber: ['', Validators.required],
country: ['', Validators.required]
});
...
如果有人可以就这里发生的事情提供一些指导,那就太好了。
我的解决方案
我重新排序了我的代码并生成了以下内容:
class EmailValidator {
static isAvailableEmail(services: RegisterServices): (AbstractControl) => Promise<ValidationResult> {
let g = (c: AbstractControl) => {
return new Promise((resolve, reject) => {
services.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
resolve({ "emailtaken": true })
},
error => {
// Need to communicate the server error? Probably not.
resolve({ "servererror": true })
});
});
};
return g;
}
}
并修改了它的用法:
...
this.registerForm = fb.group({
email: ['', Validators.required,
EmailValidator.isAvailableEmail(this._registerService)],
password: ['', Validators.compose([Validators.required, Validators.minLength(8)])],
phoneNumber: ['', Validators.required],
country: ['', Validators.required]
});
...
哪个工作正常。
你输了 this
,因为你在此处将 isAvailableEmail
作为 "raw" 函数传递:
email: ['', Validators.required, this._emailValidator.isAvailableEmail]
您可以通过将其绑定到 this
(使用粗箭头)来解决此问题:
email: ['', Validators.required,
(control) => { this._emailValidator.isAvailableEmail(control) }
]
您遇到问题是因为您正在传递 isAvailable
的值,它是一个函数。您没有执行它,您只是将引用传递给函数。
一种解决方法如
另一种方法是将 isAvailable
分配给 lambda 表达式而不是函数。像这样:
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable = (c: AbstractControl): Promise<ValidationResult> => {
let q = new Promise((resolve, reject) => {
this._registerServices.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
resolve({ "emailtaken": true })
},
error => {
// Need to communicate the server error? Probably not.
resolve({ "servererror": true })
});
});
return q;
}
}
我会提议写得有点不同
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable(c: AbstractControl): Promise<ValidationResult> {
return this._registerServices.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
return { "emailtaken": true }
})
// shorter .then(result => ({ "emailtaken": true }))
.catch(error => {
// Need to communicate the server error? Probably not.
return { "servererror": true }
});
// shorter .catch(error => ({ "servererror": true }))
});
}
}
在下面的打字稿函数中,'this' 没有解析为 EmailValidator 的实例。我如何更正此函数,使其解析为正确的 EmailVaildator 实例,然后我才能访问 _registerServices?
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable(c: AbstractControl): Promise<ValidationResult> {
let q = new Promise((resolve, reject) => {
this._registerServices.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
resolve({ "emailtaken": true })
},
error => {
// Need to communicate the server error? Probably not.
resolve({ "servererror": true })
});
});
return q;
}
}
原来'this'引用是未定义的,即使它被如下使用:
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable(c: AbstractControl): EmailValidator {
return this; // 'This' is undefined!
}
}
我认为这与方法的调用方式有关,可能是在需要静态方法的地方传递了一个非静态方法:
...
this.registerForm = fb.group({
email: ['', Validators.required, this._emailValidator.isAvailableEmail],
password: ['', Validators.compose([Validators.required, Validators.minLength(8)])],
phoneNumber: ['', Validators.required],
country: ['', Validators.required]
});
...
如果有人可以就这里发生的事情提供一些指导,那就太好了。
我的解决方案
我重新排序了我的代码并生成了以下内容:
class EmailValidator {
static isAvailableEmail(services: RegisterServices): (AbstractControl) => Promise<ValidationResult> {
let g = (c: AbstractControl) => {
return new Promise((resolve, reject) => {
services.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
resolve({ "emailtaken": true })
},
error => {
// Need to communicate the server error? Probably not.
resolve({ "servererror": true })
});
});
};
return g;
}
}
并修改了它的用法:
...
this.registerForm = fb.group({
email: ['', Validators.required,
EmailValidator.isAvailableEmail(this._registerService)],
password: ['', Validators.compose([Validators.required, Validators.minLength(8)])],
phoneNumber: ['', Validators.required],
country: ['', Validators.required]
});
...
哪个工作正常。
你输了 this
,因为你在此处将 isAvailableEmail
作为 "raw" 函数传递:
email: ['', Validators.required, this._emailValidator.isAvailableEmail]
您可以通过将其绑定到 this
(使用粗箭头)来解决此问题:
email: ['', Validators.required,
(control) => { this._emailValidator.isAvailableEmail(control) }
]
您遇到问题是因为您正在传递 isAvailable
的值,它是一个函数。您没有执行它,您只是将引用传递给函数。
一种解决方法如
另一种方法是将 isAvailable
分配给 lambda 表达式而不是函数。像这样:
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable = (c: AbstractControl): Promise<ValidationResult> => {
let q = new Promise((resolve, reject) => {
this._registerServices.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
resolve({ "emailtaken": true })
},
error => {
// Need to communicate the server error? Probably not.
resolve({ "servererror": true })
});
});
return q;
}
}
我会提议写得有点不同
class EmailValidator {
constructor(private _registerServices: RegisterServices) { }
isAvailable(c: AbstractControl): Promise<ValidationResult> {
return this._registerServices.emailIsAvailable(antiForgeryToken(), c.value)
.then(result => {
// Need to actually check the result.
return { "emailtaken": true }
})
// shorter .then(result => ({ "emailtaken": true }))
.catch(error => {
// Need to communicate the server error? Probably not.
return { "servererror": true }
});
// shorter .catch(error => ({ "servererror": true }))
});
}
}