не может правильно получить объект ошибки угловой асинхронной проверки - PullRequest
0 голосов
/ 25 апреля 2018

Я проверяю пользовательские данные, используя реактивную форму со встроенными валидаторами и пользовательским валидатором. И я хотел бы предоставить интерфейсную обратную связь / ошибки пользователям, но я не могу правильно вернуть объект ошибки проверки. Я не получаю никаких ошибок или предупреждений, и консольные журналы кажутся правильными, поэтому я действительно не знаю, что пошло не так. Вот мой код:

---- Имя службы валидаторов.valid.ts:

import { FormGroup, FormBuilder, Validators, AbstractControl } from '@angular/forms';
import { AngularFirestore } from 'angularfire2/firestore';
import { map, take } from 'rxjs/operators';

export class nameValidator {
  static validname(afs: AngularFirestore) {
    return (control: AbstractControl) => {
      const username = control.value.toLowerCase();
    console.log('username='+username)
      return afs.collection('usrs', ref => ref.where('name', '==', username) )
       .valueChanges().pipe(
          take(1),
          map(res => 
            {
              (res.length>=1) ? { 'validname': fail } : null;
            } 
          )
        )
    }
  }
}

---- Относящиеся к компоненту выдержки:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { AngularFirestoreCollection,AngularFirestoreDocument, AngularFirestore} from 'angularfire2/firestore';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { nameValidator } from  '../../validators/name.valid';

@IonicPage()
@Component({
  selector: 'page-register',
  templateUrl: 'register.html',
})
export class RegisterPage {

  formOne: FormGroup;

  constructor(public navCtrl: NavController, public navParams: NavParams
    , private afs: AngularFirestore
    , private fmBuilder: FormBuilder) 
    {

    this.formOne = this.fmBuilder.group({
      name      : ['TestnameA', Validators.compose([Validators.required ,Validators.pattern('[a-zA-Z]*')])
                    ,nameValidator.validname(this.afs)],
      password  : ['testaa', Validators.compose([Validators.required ,Validators.minLength(5)])],
    }); 

  }//end constructor

---- Шаблон / html соответствующие выдержки:

<ion-content>
        <form novalidate [formGroup]="formOne">
            <input id="name" type="text" formControlName="name" required>

            <div *ngIf="name.invalid && name.dirty" >
                {{ name.value }} is already taken
            </div>

            <div *ngIf="name.valid">
                {{ name.value }} is available
            </div>

            <div *ngIf="name.pending">
                Checking availability of {{ name.value }}
            </div>
         </form>
     </ion-content>

Когда я ввожу имя, которое уже занято в моей базе данных firestore, имя по-прежнему будет ошибочно помечено как действительное во внешнем интерфейсе. Но из отладки brekapoints в моем сервисном коде nameValidator я знаю, что res.length равен 1. Так или иначе, валидатор может обнаружить ошибка проверки, но не вернул правильный статус.
Я также отметил, что мой валидатор является асинхронным, поэтому он помещается в качестве 3-го аргумента formbuilderGroup, и я также пытался добавить задержки в свои проверки, но без разницы.
Буду благодарен за любые советы. Благодарю.

1 Ответ

0 голосов
/ 26 апреля 2018

В Angular 5 служба асинхронного валидатора должна иметь следующий синтаксис, чтобы она работала:

 import { AsyncValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms';
import { AngularFirestore } from 'angularfire2/firestore';
import { Observable } from "rxjs/Observable";
import { map, take } from 'rxjs/operators';

export class nameValidator {
      static validname(afs: AngularFirestore): AsyncValidatorFn  {
        return (control: AbstractControl): Observable<ValidationErrors> => {
          const username = control.value.toLowerCase();
        console.log('username='+username)
          return afs.collection('usrs', ref => ref.where('name', '==', username) )
           .valueChanges().pipe(
              take(1),
              map(res => 
                {
                 return (res.length>=1) ? { 'validname': fail } : null;
                } 
              )
            )
        }
      }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...