【发布时间】:2020-04-07 19:58:03
【问题描述】:
我正在使用自定义异步验证器构建反应式表单。 验证器使用 Angular 的 HTTP 客户端向我的服务器(在 node.js 上运行)发出请求,并使用接收表单控件值的回调函数。 这个想法是检查表单中输入的提交的ID是否已经存在于数据库中。 服务器调用正常工作。调用,返回值(如果存在)返回一个长度为1的对象,不存在时返回null。
问题是,调用的状态保持为未决状态并阻止表单变为有效状态(我将提交按钮链接到表单底部,就像 [disabled]="!newUser.valid" 一样,因为异步验证器的状态保持等待状态,并且 observable 永远不会完成,按钮保持禁用状态。
我已尝试订阅 observable,但随后出现以下错误?: ((c: FormControl) => Subscription | Observable)[]' 不可分配给'AsyncValidatorFn | AsyncValidatorFn[]
Register.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { matchOtherValidator } from '../match-other-validator';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { map} from 'rxjs/operators';
const tzAsyncValidator = (http: HttpClient) => (c: FormControl) => {
console.log(c.parent);
if (!c || String(c.value).length === 0) {
console.log("!c|| String (c.value).length ===0")
return of(null);
}
return http.get('http://localhost:4000/userIds/' + String(c.value))
.pipe(
map((ids: any[]) => {
console.log(ids);
if (ids.length === 1) {
console.log(c.parent.status);
console.log(c.status);
return { exists: true }
}
if (ids.length === 0) {
console.log(c.parent.status);
console.log(c.status);
return { exists: null};
}
}
)
)
.subscribe()
;
}
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
public newUser;
public verification;
constructor(private http: HttpClient) { }
ngOnInit() {
this.newUser = new FormGroup({
Tz: new FormControl('', [Validators.required, Validators.minLength(4), Validators.maxLength(9)], [tzAsyncValidator(this.http)]),
Email: new FormControl('', [Validators.required, Validators.email]),
PW: new FormControl('', [Validators.required, Validators.pattern('^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$')]),
PWVerification: new FormControl('', [Validators.required, Validators.pattern('^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$'), matchOtherValidator('PW')])
})
}
}
Register.component.html
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#staticBackdrop">
Sign up!
</button>
<!-- Modal -->
<div class="modal fade" id="staticBackdrop" data-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Sign Up!</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form [formGroup]="newUser" (ngSubmit)='onSubmit()' >
<label>ID</label>
<br>
<input type="text" placeholder="Please Enter Your ID" formControlName="Tz">
<br>
<label>Email</label>
<br>
<input type="email" placeholder="Please Enter Your Email" formControlName="Email">
<br>
<label>Password</label>
<br>
<input type="text" name="password" placeholder="Please Choose A Password" formControlName="PW" size="25">
<br>
<label>Resubmit Your Password</label>
<br>
<input type="text" name="confirmPassword" placeholder="Please Resubmit Your Password" formControlName="PWVerification" validateEqual="password" size="30" >
<br>
<input type="submit" class="btn btn-success" [disabled]="!newUser.valid" >
<br>
<span *ngIf="newUser.get('Email').invalid &&!newUser.get('Email').pristine">Your email does not look right</span>
<br>
<span *ngIf="newUser.get('Tz').errors?.minlength">Your ID must be at least 4 digits long</span>
<br>
<span *ngIf="newUser.get('Tz').errors?.maxlength">The maximum ID length is 9 digits</span>
<br>
<span *ngIf="newUser.get('PW').invalid&&!newUser.get('PW').pristine">Password must include at least one letter and one digit</span>
<br>
<span *ngIf="newUser.get('PWVerification').errors?.matchOther">Your submitted passwords don't match</span>
<br>
<span *ngIf="newUser.get('Tz').errors?.exists">This ID already exists</span>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
【问题讨论】:
标签: angular observable angular-reactive-forms