访问'这个'内心承诺

时间:2016-05-18 00:32:18

标签: typescript angular scoping

在下面的打字稿功能中,'这个'没有解析为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;
    }
}

4 个答案:

答案 0 :(得分:8)

您正在失去this,因为您正在绕过isAvailableEmail作为&#34; raw&#34;功能在这里:

email: ['', Validators.required, this._emailValidator.isAvailableEmail]

您可以通过将其绑定到this(使用胖箭头)来解决此问题:

email: ['', Validators.required,
  (control) => { this._emailValidator.isAvailableEmail(control) }
]

答案 1 :(得分:1)

事实证明,'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]
    });
...

哪种方法正常。

答案 2 :(得分:1)

您遇到了问题,因为您传递的是isAvailable的值,这是一个函数。你没有执行它,你只是将引用传递给函数。

解决问题的一种方法是@Thilo's answer

另一种方法是将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;
    }
}

答案 3 :(得分:0)

我会提议写一点不同

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 }))

        });

    }
}