Angular 2-自定义表单验证器不起作用

时间:2019-05-21 14:19:21

标签: angular

此自定义表单验证器存在问题

这是我的表单生成器:

buildForm(): void {

    this.step1Form = this.fb.group({
        username: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(4)],
        }),
        email: new FormControl('', {
                validators: [Validators.required,
                Validators.pattern("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")],
        }),
        password: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(8)],
        }),
        repeat: new FormControl('', {
                validators: [Validators.required,
                Validators.minLength(8)],
        }),
        }, { validator: this.checkUsername.bind(this)});

    this.activeForm = this.step1Form;

}

这是checkUsername方法

checkUsername(g: FormGroup) {
    this.dataService.checkUsername(g.get('username').value).subscribe(data => {
            return typeof data["error"] != 'undefined' ? null : {'taken': true};
    });
}

当我在用户名字段中键入内容时,我看到我的方法正在被调用,当找不到用户名时,它返回{“ error”:true,“ 0”:“ User not found!”}},并返回的json数据用户(如果找到)。

我的问题是我有这个下一个按钮,并且当表单无效时应该被禁用,但是当我输入用户名时我知道已经使用了该按钮:

<div [ngClass]="{'text-right': tabActive != 5}">
    <button [ngClass]="{'mr-30': tabActive != 5}"
    [disabled]="!activeForm.valid" 
    class="save-btn next-btn" (click)="next()">
    {{ tabActive == 5 ? "Finish" : "Next" }} <i class="fa fa-angle-right"></i>
    </button>
</div>

这是实际的形式。我的问题是我做错了什么?我可以看到该方法正在被调用,并且返回了应有的结果,使用用户名时不会使我的表单无效

    <form [formGroup]="step1Form">
    <div class="col-md-4">
            <input type="file" id="profile-image" (change)="selectFile($event)" name="image" accept="image/*" capture style="display:none"/>
            <img src="assets/images/image-upload.png" (click)="profileImgClick($event)" />
    </div>
    <div class="col-md-8">
    <div class="info" *ngIf="errors.taken">
            <i class="fa fa-info-circle"></i>The username is already in use
    </div>
    <div class="form-group">
        <span class="icon"><i class="far fa-user"></i></span>
        <input [(ngModel)]="patient.patient_username" formControlName="username" type="text" maxlength="9" class="form-control control-icon" placeholder="Username">
        <div *ngIf="errors.username" class="error">{{ errors.username }}</div>
    </div>
    <div class="form-group">
        <span class="icon"><i class="fa fa-envelope"></i></span>
        <input [(ngModel)]="patient.email" formControlName="email" type="text" class="form-control control-icon" placeholder="Your email">
        <div *ngIf="errors.email" class="error">{{ errors.email }}</div>
    </div>
    <div class="form-group">
        <span class="icon"><i class="fa fa-key"></i></span>
        <input [(ngModel)]="patient.password" formControlName="password" type="password" class="form-control control-icon" placeholder="Password">
        <div *ngIf="errors.password" class="error">{{ errors.password }}</div>
    </div>
    <div class="form-group">
        <span class="icon"><i class="fa fa-key"></i></span>
        <input formControlName="repeat" type="password" class="form-control control-icon" placeholder="Repeat password">
        <div *ngIf="errors.repeat" class="error">{{ errors.repeat }}</div>
    </div>
    </div>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</form>

这是dataService.checkUsername

checkUsername(username):Observable<any> {
            return this.http.get(globals.baseUrl+'/user/' + username, {headers:this.utilService.getHeadersJson()}).map(this.utilService.map);
        }

1 个答案:

答案 0 :(得分:0)

从异步验证器返回一个Observable。

checkUsername(g: FormGroup) {
    return this.dataService.checkUsername(g.get('username').value).pipe(map(data => {
        return typeof data["error"] != 'undefined' ? null : {'taken': true};
    }));
}

我认为应该将验证器添加到用户名控件中?不是吗?

username: new FormControl('', 
    {validators: [Validators.required, Validators.minLength(4)],
    asyncValidators: [this.checkUsername.bind(this)]}
),