2016-08-30 1 views
2

У меня есть проблема со следующей функцией валидатора:Проблема с функцией проверки подлинности не устанавливая объект ошибки на контроле формы

export function validateEmailKnownFactory(userAccountService: UserAccountService): {[key: string]: any} { 
    return (control: AbstractControl) => { 
    return control 
     .valueChanges 
     .debounceTime(1000) 
     .switchMap(value => userAccountService.checkAvailability(value)) 
     .map(res => { 
     if (res.json() === false) { 
      return null; 
     } 
     //Control flow does get through here 
     return {emailKnownValidator: {unknown: true}}; 
     }); 
    }; 
} 

Не устанавливающее объект ошибки (т.е. {emailKnownValidator: {unknown: true}}) на элементе управления, но управление потоком попадает в нужное место.

Теперь, если я заменю выше функцию следующим:

export function validateEmailKnownFactory(userAccountService: UserAccountService): {[key: string]: any} { 
    return (control: AbstractControl) => { 
    return userAccountService.checkAvailability(control.value) 
     .map(res => { 
     if (res.json() === false) { 
      return null; 
     } 
     return {emailKnownValidator: {unknown: true}}; 
     }); 
    }; 
} 

объект ошибки устанавливается штраф на элементе управления и приложение ведет себя, как ожидалось.

Обратите внимание на разницу: Я получаю Observable от control.valueChanges и я называю debounceTime на нем в то время как другие функции, просто вызовите checkAvailability непосредственно.

Для полноты ради здесь является checkAvailability метод:

checkAvailability(email: string) { 
    let body = 'email=' + email; 
    return this.http.get(this.urls.USER_ACCOUNT.EMAIL_AVAILABLE + body); 
    } 

ответ

2

Асинхронные валидатор функции в угловых 2 может возвращать либо Promise или Observable. Если возвращается Observable, он должен заполнить - как Угловой converts the Observable to a Promise. То есть Observable используется так, чтобы проверка могла быть асинхронной - не так, чтобы валидатор мог подавать поток результатов.

Observable составлен из valueChanges в вашем первом валидаторе не заполнен - ​​как valueChanges сохраняет откачивающие изменения. Это означает, что Promise не разрешает и нет результата проверки, который может быть применен к элементу управления. (Обратите внимание, что Angular будет вызывать вашу функцию проверки для каждого изменения в значении элемента управления, и каждый вызов будет видеть Observable, составленный и подписанный, поэтому checkAvailability будет вызываться для каждого изменения. Оператор debounceTime не будет влиять на поведение вы, похоже, хотите.)

Observable, возвращаемый функцией checkAvailability, завершает работу, поэтому ваша вторая функция валидатора работает.

+0

Спасибо за подробное объяснение. Есть один последний момент, на который я был бы благодарен вам за разъяснение: хотите ли вы сказать, что «debounceTime» не достигнет эффекта, который я хочу, потому что наблюдаемый «подписался на *»? – balteo

+0

Преобразование в 'Promise' будет связано с подпиской, но на самом деле это не проблема. Это тот факт, что каждый вызов валидатора возвращает свой собственный «Observable», который цепочки «valueChanges» на основе «Observable» на основе HTTP из «checkAvailability», поэтому каждый вызов всегда будет видеть последнее изменение, внесенное в 'checkAvailability '. Вы можете использовать 'debounceTime' для создания« Observable », чтобы получить желаемый эффект, но вы не можете составить его внутри валидатора, так как это приведет к тому, что каждый вызов будет составлять отдельный« Наблюдаемый ». – cartant

+0

Надеюсь, это имеет смысл. Здесь немного поздно. – cartant

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

  • Нет связанных вопросов^_^