我试图通过说一个用户名是否可用异步验证器来验证用户名,我尝试了许多解决方案,但我不知道要完成这项工作,我遇到了这个错误:
Error: Expected validator to return Promise or Observable.
我的方法validateUsername()不完整,如何使它工作?
register.component.ts
this.registerForm = this.fb.group({
username: ['', [Validators.required], this.validateUsername.bind(this)],
email: ['', [Validators.required,
Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$')]],
password: this.fb.group({
pwd: ['', [Validators.required, Validators.minLength(1)]], // todo
confirmpwd: ['', [Validators.required, Validators.minLength(1)]]// todo
}, {
validator: this.mustMatch('pwd', 'confirmpwd'),
}),
birthday: ['', Validators.required]
});
}
validateUsername(control: AbstractControl) {
this.userservice.checkUserExist(control.value).subscribe(
res => {
this.exist = 'username available ';
},
error => {
this.exist = 'username unavailable ';
}
);
}
register.component.html
<div class="form-group">
<label for="inputName" class="font-weight-bold">Usuario</label>
<div class="input-group Name">
<div class="input-group-prepend">
<div class="input-group-text"><i class="fa fa-user" aria-hidden="true"></i>
</div>
</div>
<input type="text" class="form-control" id="inputName" name="inputName" formControlName="username"
placeholder="Identificador de usuario">
</div>
<div *ngIf="username.invalid && username.touched" class="col-4 p-0 ml-5 text-danger">
<p *ngIf="username.errors?.required">
Escoger un nombre de usuario
</p>
<p *ngIf="username.errors?.usertaken">
Este usuario ya existe
</p>
</div>
</div>
答案 0 :(得分:2)
这是给你的例子
一个简单的组件初始化我们的反应形式并定义我们的异步验证器:validateEmailNotTaken。请注意,FormBuilder.group声明中的表单控件如何将异步验证器作为第三个参数。在这里,我们仅使用一个异步验证器,但您希望将多个异步验证器包装在一个数组中:
app.component.ts
import { Component, OnInit } from '@angular/core';
import {
FormBuilder,
FormGroup,
Validators,
AbstractControl
} from '@angular/forms';
import { SignupService } from './signup.service';
@Component({ ... })
export class AppComponent implements OnInit {
myForm: FormGroup;
constructor(
private fb: FormBuilder,
private signupService: SignupService
) {}
ngOnInit() {
this.myForm = this.fb.group({
name: ['', Validators.required],
email: [
'',
[Validators.required, Validators.email],
this.validateEmailNotTaken.bind(this)
]
});
}
validateEmailNotTaken(control: AbstractControl) {
return this.signupService.checkEmailNotTaken(control.value).map(res => {
return res ? null : { emailTaken: true };
});
}
}
我们的验证器与典型的自定义验证器非常相似。在这里,我们直接在组件类中定义了验证器,而不是单独的文件。这使得访问我们注入的服务实例更加容易。还请注意,我们如何绑定此值以确保它指向组件类。
我们还可以在自己的文件中定义异步验证器,以便更轻松地重用和分离关注点。唯一棘手的部分是找到一种提供我们的服务实例的方法。例如,在这里,我们创建一个类,该类具有一个createValidator静态方法,该方法接受我们的服务实例并返回我们的验证函数:
async-email.validator.ts
import { AbstractControl } from '@angular/forms';
import { SignupService } from '../signup.service';
export class ValidateEmailNotTaken {
static createValidator(signupService: SignupService) {
return (control: AbstractControl) => {
return signupService.checkEmailNotTaken(control.value).map(res => {
return res ? null : { emailTaken: true };
});
};
}
}
然后,回到我们的组件中,我们导入ValidateEmailNotTaken类,我们可以像这样使用验证器:
ngOnInit() {
this.myForm = this.fb.group({
name: ['', Validators.required],
email: [
'',
[Validators.required, Validators.email],
ValidateEmailNotTaken.createValidator(this.signupService)
]
});
}
HTML文件
<form [formGroup]="myForm">
<input type="text" formControlName="name">
<input type="email" formControlName="email">
<div *ngIf="myForm.get('email').status === 'PENDING'">
Checking...
</div>
<div *ngIf="myForm.get('email').status === 'VALID'">
Email is available!
</div>
<div *ngIf="myForm.get('email').errors && myForm.get('email').errors.emailTaken">
this email is already taken!
</div>
</form>
答案 1 :(得分:0)
表格
public registerForm: FormGroup;
constructor(private authService:AuthentificationService,
private formBuilder: FormBuilder,
) { }
this.registerForm = this.formBuilder.group({
firstname: ['', Validators.required],
lastname: ['', Validators.required],
username: ['', [Validators.required,this.validateUsername()]],
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6)]],
confirmPassword: ['', Validators.required]
}, {
validator: MustMatch('password', 'confirmPassword')
});
get f() { return this.registerForm.controls; } // convenience getter for easy access to form fields
验证器
private validateUsername(): ValidatorFn {
return (control: AbstractControl) => {
if (control.value.length != 0) {
this.authService.checkUsername(control.value).subscribe( data => {
if(data) control.setErrors({'alreadyExist': true}) ;
else return null;
})
}else return null;
}
}
HTML
<mat-form-field>
<input matInput placeholder="User Name" required autocomplete="off" formControlName="username">
<mat-icon matSuffix>perm_identity</mat-icon>
<mat-error *ngIf= "f.username.errors?.required">
Username is required
</mat-error>
<mat-error *ngIf= " f.username.errors?.alreadyExist">
this username already exists in our database
</mat-error>
</mat-form-field>