2016-05-18 2 views
5

В приведенной ниже функции машинописного текста «это» не разрешается экземпляру 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; 
    } 
} 
+1

Хм. Похоже, жирная стрела уже должна это делать. И, глядя на сгенерированный Javascript, он, похоже, правильно описывает это. Вы уверены, что это проблема, которую вы видите? – Thilo

+0

@Thilo С тех пор я обнаружил, что проблема немного скрыта, и проблема была в другом месте. Я обнаружил, как исправить мою проблему, но есть детали вокруг «почему» возникла проблема, что я действительно ценю некоторые рекомендации. Я отправлю свое решение. –

ответ

7

Вы теряете this, потому что вы передаете вокруг isAvailableEmail как «сырой» функции здесь:

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

Вы можете исправить это путем связывания его this (с использованием жировой стрелки):

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

Спасибо Thilo. Мне нравится ваше решение - это самое малое изменение, но я буду придерживаться своего, потому что это согласуется с тем, как, по-видимому, команда Angular реализовала свои валидаторы. Я отвечу на ваш ответ как принятый, потому что он наилучшим образом отвечает на исходный вопрос. –

+0

Обратите внимание, что у них есть «статические» функции, такие как 'Validators.required', которые не нужно настраивать, и фабрики валидатора, которые генерируют функцию валидатора, которые фиксируют всю их конфигурацию, например' Validators.minLength (8) '.Вы можете сделать что-то вроде «EmailValidator (registerServices)» для создания функции, которая захватывает «registerServices» и делает то, что делает ваш 'isAvailableEmail'. – Thilo

+0

Итак, валидатор не должен быть классом, как функция, которая создает другую функцию (например, ваш 'isAvailableEmail'). И эта сгенерированная функция является самодостаточной. – Thilo

1

Оказалось, что «это» ссылка была не определена, даже если она была использована следующим образом:

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

который работает правильно.

1

У вас возникла проблема, потому что вы передаете значение isAvailable, которое является функцией. Вы не выполняете его, вы просто передаете ссылку на функцию.

Один из способов решить эту проблему как в @Thilo's answer

Другой способ заключается в назначении isAvailable для лямбда-выражения вместо функции. как это:

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

я хотел бы предложить, чтобы написать это немного другое

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

     }); 

    } 
} 
Смежные вопросы