自定义验证器反应形式离子
Custom Validator Reactive Form Ionic
这是我第一次使用自定义验证器。我遵循了本指南 https://ionicthemes.com/tutorials/about/forms-and-validation-in-ionic 。基本上我想检查用户名是否已被使用,如果是,更新配置文件按钮未启用。但它不起作用,如果我尝试以 firebase 的实时数据库中已存在的用户名的形式输入该按钮,则该按钮已启用,但在控制台中我收到消息“username già in uso”。我是不是对 UsernameValidator class 做错了什么?
import { FormControl } from '@angular/forms';
import * as firebase from 'firebase';
export class UsernameValidator {
static validUsername(fc: FormControl){
firebase.database().ref().child("users").orderByChild("username")
.equalTo(fc.value)
.once("value",snapshot => {
if (snapshot.exists()){
console.log("username già in uso")
return ({validUsername: false});
}
else
return (null);
});
}
}
这是我定义表单组和验证器的地方:
constructor(private route: ActivatedRoute, private router: Router,
public pfService: ProfileService, public fb: FormBuilder,
public authService: AuthenticationService)
{
this.id = this.authService.userData.uid;
//Underscore and dot can't be next to each other (e.g user_.name).
//Underscore or dot can't be used multiple times in a row (e.g user__name / user..name).
this.validPattern = "^(?=.{6,20}$)(?!.*[_.]{2})[a-z0-9._]+$";
this.validPatternName = "^[a-z]{3,10}$";
this.userForm = fb.group({
txtUsername: ["",[Validators.required,Validators.pattern(this.validPattern),
UsernameValidator.validUsername]],
txtName: ["",[Validators.required,Validators.pattern(this.validPatternName)]],
});
};
这是 HTML 代码:
<form [formGroup]="userForm" (ngSubmit)="updateForm()" >
<ion-item>
<ion-label class="form-control" position="floating">Userame</ion-label>
<ion-input formControlName="txtUsername" type="text" ></ion-input>
<span [hidden]="userForm.controls.txtUsername.valid || userForm.controls.txtUsername.pristine">Lunghezza tra 6 e 20 caratteri</span>
</ion-item>
<ion-item>
<ion-label class="form-control" position="floating">Name</ion-label>
<ion-input formControlName="txtName" type="text" > </ion-input>
<span [hidden]="userForm.controls.txtName.valid || userForm.controls.txtName.pristine">Lunghezza tra 6 e 20 caratteri</span>
</ion-item>
<ion-row>
<ion-col>
<ion-button type="submit" *ngIf="userForm.controls.txtUsername.valid && userForm.controls.txtName.valid " color="primary" shape="full" expand="block">Update Profile</ion-button>
</ion-col>
</ion-row>
</form>
首先,我建议您的验证器 returns :
return ({validUsername: true});
如果您想在每次输入字符时检查验证器状态,我建议在表单声明后添加构造器:
this.userForm .valueChanges.subscribe(()=> {
console.log(this.userForm.getError('validUsername'))
})
此外,也许你的验证器不会 return 任何东西,因为它会卡在快照中,你会知道你的 userForm.getError('validUsername') 是否仍然 return null 即使你得到了“用户名 già in uso”。
因为你的 firebase 查询是一个异步函数,试试这个:
static validUsername(fc: FormControl){
firebase.database().ref().child("users").orderByChild("username")
.equalTo(fc.value)
.once("value",async snapshot => {
if (snapshot.exists()){
console.log("username già in uso")
return await ({validUsername: true});
}
else
return (null);
});
}
或
static validUsername(fc: FormControl){
let bool:boolean =this.getSnapshot(fc.value)
if(bool===true)
return ({validUsername: true});
}
else{
return (null);
}
});
}
async getSnapshot(value:string):boolean{
let bool:boolean
await firebase.database().ref().child("users").orderByChild("username")
.equalTo(fc.value)
.once("value",snapshot => {
if (snapshot.exists()){
bool=true
console.log("username già in uso")
}
else{
bool=false
}
});
}
这是我第一次使用自定义验证器。我遵循了本指南 https://ionicthemes.com/tutorials/about/forms-and-validation-in-ionic 。基本上我想检查用户名是否已被使用,如果是,更新配置文件按钮未启用。但它不起作用,如果我尝试以 firebase 的实时数据库中已存在的用户名的形式输入该按钮,则该按钮已启用,但在控制台中我收到消息“username già in uso”。我是不是对 UsernameValidator class 做错了什么?
import { FormControl } from '@angular/forms';
import * as firebase from 'firebase';
export class UsernameValidator {
static validUsername(fc: FormControl){
firebase.database().ref().child("users").orderByChild("username")
.equalTo(fc.value)
.once("value",snapshot => {
if (snapshot.exists()){
console.log("username già in uso")
return ({validUsername: false});
}
else
return (null);
});
}
}
这是我定义表单组和验证器的地方:
constructor(private route: ActivatedRoute, private router: Router,
public pfService: ProfileService, public fb: FormBuilder,
public authService: AuthenticationService)
{
this.id = this.authService.userData.uid;
//Underscore and dot can't be next to each other (e.g user_.name).
//Underscore or dot can't be used multiple times in a row (e.g user__name / user..name).
this.validPattern = "^(?=.{6,20}$)(?!.*[_.]{2})[a-z0-9._]+$";
this.validPatternName = "^[a-z]{3,10}$";
this.userForm = fb.group({
txtUsername: ["",[Validators.required,Validators.pattern(this.validPattern),
UsernameValidator.validUsername]],
txtName: ["",[Validators.required,Validators.pattern(this.validPatternName)]],
});
};
这是 HTML 代码:
<form [formGroup]="userForm" (ngSubmit)="updateForm()" >
<ion-item>
<ion-label class="form-control" position="floating">Userame</ion-label>
<ion-input formControlName="txtUsername" type="text" ></ion-input>
<span [hidden]="userForm.controls.txtUsername.valid || userForm.controls.txtUsername.pristine">Lunghezza tra 6 e 20 caratteri</span>
</ion-item>
<ion-item>
<ion-label class="form-control" position="floating">Name</ion-label>
<ion-input formControlName="txtName" type="text" > </ion-input>
<span [hidden]="userForm.controls.txtName.valid || userForm.controls.txtName.pristine">Lunghezza tra 6 e 20 caratteri</span>
</ion-item>
<ion-row>
<ion-col>
<ion-button type="submit" *ngIf="userForm.controls.txtUsername.valid && userForm.controls.txtName.valid " color="primary" shape="full" expand="block">Update Profile</ion-button>
</ion-col>
</ion-row>
</form>
首先,我建议您的验证器 returns :
return ({validUsername: true});
如果您想在每次输入字符时检查验证器状态,我建议在表单声明后添加构造器:
this.userForm .valueChanges.subscribe(()=> {
console.log(this.userForm.getError('validUsername'))
})
此外,也许你的验证器不会 return 任何东西,因为它会卡在快照中,你会知道你的 userForm.getError('validUsername') 是否仍然 return null 即使你得到了“用户名 già in uso”。
因为你的 firebase 查询是一个异步函数,试试这个:
static validUsername(fc: FormControl){
firebase.database().ref().child("users").orderByChild("username")
.equalTo(fc.value)
.once("value",async snapshot => {
if (snapshot.exists()){
console.log("username già in uso")
return await ({validUsername: true});
}
else
return (null);
});
}
或
static validUsername(fc: FormControl){
let bool:boolean =this.getSnapshot(fc.value)
if(bool===true)
return ({validUsername: true});
}
else{
return (null);
}
});
}
async getSnapshot(value:string):boolean{
let bool:boolean
await firebase.database().ref().child("users").orderByChild("username")
.equalTo(fc.value)
.once("value",snapshot => {
if (snapshot.exists()){
bool=true
console.log("username già in uso")
}
else{
bool=false
}
});
}