2016-05-18 22 views
5

Trong chức năng đánh số dưới đây, 'this' không giải quyết được ví dụ của EmailValidator. Làm thế nào tôi có thể sửa chức năng này để nó giải quyết đúng thể hiện của EmailVaildator và đến lượt nó, để tôi có thể truy cập _registerServices?Truy cập 'this' Inside Promise

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; 
    } 
} 
+1

Hmm. Có vẻ như mũi tên béo đã được thực hiện. Và nhìn vào Javascript được tạo ra, nó dường như bí danh 'này' đúng. Bạn có chắc đó là vấn đề bạn đang thấy không? – Thilo

+0

@Thilo Tôi đã phát hiện ra vấn đề là một chút ẩn và vấn đề là ở nơi khác. Tôi đã khám phá cách khắc phục sự cố của mình, nhưng có những chi tiết xung quanh 'tại sao' vấn đề xảy ra mà tôi thực sự đánh giá cao một số hướng dẫn. Tôi sẽ đăng giải pháp của tôi. –

Trả lời

7

Bạn đang mất this, bởi vì bạn đang đi qua xung quanh isAvailableEmail như một chức năng "thô" ở đây:

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

Bạn có thể khắc phục điều này bằng cách gắn nó vào this (bằng cách sử dụng mũi tên chất béo):

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

Cảm ơn Thilo. Tôi thích giải pháp của bạn - đó là sự thay đổi nhỏ nhất - nhưng sẽ gắn bó với tôi, bởi vì nó phù hợp với cách mà nhóm Angular dường như đã triển khai trình xác nhận của họ. Tôi sẽ trả lời câu trả lời của bạn là câu trả lời vì nó trả lời tốt nhất câu hỏi ban đầu. –

+0

Lưu ý rằng chúng có các hàm "tĩnh" như 'Validators.required' mà không cần phải được cấu hình, và các nhà máy validator tạo ra hàm validator để nắm bắt tất cả cấu hình của chúng, như' Validators.minLength (8) '.Bạn có thể làm một cái gì đó như 'EmailValidator (registerServices)' để tạo ra một chức năng mà nắm bắt 'registerServices' và làm những gì' isAvailableEmail' của bạn. – Thilo

+0

Vì vậy, trình xác thực không được là một lớp quá nhiều như một hàm tạo ra một hàm khác (như 'isAvailableEmail') của bạn. Và chức năng được tạo ra đó là khép kín. – Thilo

1

Hóa ra là tài liệu tham khảo 'này' đã không xác định ngay cả khi nó đã được sử dụng như sau:

class EmailValidator { 

    constructor(private _registerServices: RegisterServices) { } 

    isAvailable(c: AbstractControl): EmailValidator { 
     return this; // 'This' is undefined! 
    } 
} 

tôi thu thập này có gì để làm với cách phương pháp này được gọi là, có lẽ đi qua một phương pháp không tĩnh nơi phương thức tĩnh được mong đợi:

... 
this.registerForm = fb.group({ 
    email: ['', Validators.required, this._emailValidator.isAvailableEmail], 
    password: ['', Validators.compose([Validators.required, Validators.minLength(8)])], 
    phoneNumber: ['', Validators.required], 
    country: ['', Validators.required] 
    }); 
... 

Nếu ai đó có thể cung cấp một số hướng dẫn về những gì đang xảy ra ở đây, điều đó thật tuyệt vời.

My Giải pháp

Tôi sắp xếp lại mã của tôi và sản xuất như sau:

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

Và sửa đổi sử dụng của nó:

... 
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] 
    }); 
... 

Những hoạt động chính xác.

1

Bạn gặp sự cố vì bạn đang chuyển giá trị isAvailable là một hàm. Bạn không thực hiện nó, bạn chỉ cần chuyển tham chiếu đến hàm.

Một cách để giải quyết nó là như trong @Thilo's answer

Một cách khác là gán isAvailable để một biểu thức lambda thay vì một hàm. như thế này:

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; 
    } 
} 
0

tôi sẽ cung cấp để viết nó một chút khác nhau

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

     }); 

    } 
} 
Các vấn đề liên quan