无法正确获取 angular 异步验证错误对象
cannot correctly get angular asynchronous validation error object
我正在使用带有内置验证器和自定义验证器的反应式表单来验证用户输入。我想
向用户提供前端 feedback/errors,但我似乎无法正确取回验证错误对象。
我没有收到任何错误或警告,控制台日志似乎是正确的,所以我真的不知道出了什么问题。
这是我的代码:
----验证者服务name.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
----Template/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 数据库中使用的名称时,该名称仍会在前端错误地标记为有效。
但是通过在我的 nameValidator 服务代码中调试 brekapoints,我知道 res.length 是 1。所以不知何故,验证器能够检测到
验证错误,但没有 return 正确的状态。
我还注意到我的验证器是异步的,因此它被放置为第三个参数 formbuilderGroup 我也尝试在我的检查中添加延迟,但没有任何区别。
将不胜感激任何建议。谢谢。
在 Angular 5 中,Async 验证程序服务应具有以下语法才能工作:
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;
}
)
)
}
}
}
我正在使用带有内置验证器和自定义验证器的反应式表单来验证用户输入。我想 向用户提供前端 feedback/errors,但我似乎无法正确取回验证错误对象。 我没有收到任何错误或警告,控制台日志似乎是正确的,所以我真的不知道出了什么问题。 这是我的代码:
----验证者服务name.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
----Template/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 数据库中使用的名称时,该名称仍会在前端错误地标记为有效。
但是通过在我的 nameValidator 服务代码中调试 brekapoints,我知道 res.length 是 1。所以不知何故,验证器能够检测到
验证错误,但没有 return 正确的状态。
我还注意到我的验证器是异步的,因此它被放置为第三个参数 formbuilderGroup 我也尝试在我的检查中添加延迟,但没有任何区别。
将不胜感激任何建议。谢谢。
在 Angular 5 中,Async 验证程序服务应具有以下语法才能工作:
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;
}
)
)
}
}
}