angular - Angular Async Validator FormControls 在模糊之前不会更新
问题描述
我的异步验证器如下所示:
asyncValidator(service:ApiCallsService):AsyncValidatorFn{
return (control:FormControl):Promise<ValidationErrors | null> | Observable<ValidationErrors | null> =>{
let timer$ = timer(2000);
return timer$.pipe(
take(1),
switchMap(()=> {
let videoId = service.checkUrl(control.value);
return service.getVideoDescription(videoId).toPromise().then((val:any)=>{
return (!val.id) ? {"invalidUrl": true} : null;
})
})
)
}
}
我的异步验证器的问题在于,添加到我的 FormArray 中的 FormControl 在它们被模糊之前不会获取它们自身的当前“状态”。
这是我的 FormArray 和里面的 FormControl:
<div class="url-con" formArrayName="urls" >
<div *ngFor="let url of urls.controls; let i=index" class="url-input-con">
<input minLength="5" placeholder="Video Url" class="url-input" [formControlName]="i">
<div class="url-pending" *ngIf="urls.controls[i].pending && !urls.controls[i].valid">Validating...</div>
</div>
</div>
具有“url-pending”类的 div 出现,然后它不会消失 - 即使它所依赖的 FormControl 由后端验证 - 直到用户模糊了 div 所依赖的 FormControl。
与此类似的唯一其他 stackoverflow 问题是此链接。我无法完全理解该链接的说明,并且与链接的海报相比,我遇到的另一个复杂情况是我的表单中有一个形状为加号的图标,以便用户可以向 FormArray 添加更多的 FormControl。我不知道如何向用户通过与表单交互添加的 FormControls 添加指令。
我会回答我自己的问题,因为我想出了如何解决这个问题,但我以一种“hackish”的方式解决了它。如果其他人对此有更好的答案,请回复。
解决方案
我向 formArray (#formArray) 添加了一个标识符:
<div #formArray class="url-con" formArrayName="urls" >
<div *ngFor="let url of urls.controls; let i=index" class="url-input-con">
<input minLength="5" placeholder="Video Url" class="url-input" [formControlName]="i">
<div class="url-pending" *ngIf="urls.controls[i].pending && !urls.controls[i].valid">Validating...</div>
</div>
</div>
然后我将 finalize() 添加到异步验证器中 timer$ 的返回中。在操作符的回调中,我将 FormArray 的每个 FormControl 设为焦点,然后进行模糊处理。
asyncValidator(service:ApiCallsService):AsyncValidatorFn{
return (control:FormControl):Promise<ValidationErrors | null> | Observable<ValidationErrors | null> =>{
let timer$ = timer(2000);
return timer$.pipe(
take(1),
switchMap(()=> {
let videoId = service.checkUrl(control.value);
return service.getVideoDescription(videoId).toPromise().then((val:any)=>{
return (!val.id) ? {"invalidUrl": true} : null;
})
}),
finalize(()=>{
Array.from(this.formArray.nativeElement.children)
.forEach((val:HTMLElement,ind)=>{
(Array.from(val.children)[0] as HTMLElement).focus();
(Array.from(val.children)[0] as HTMLElement).blur();
})
})
)
}
}
每个 FormControl 必须首先聚焦,因为如果用户在验证结束之前模糊,那么 FormControl 永远不会模糊,并且“待定”状态会永远持续显示(尽管在功能上不是)。
推荐阅读
- python - 遍历数据框,根据值创建字典
- vba - VBA 宏:在工作表中使用 vlaues 指定 Sheets()
- graphql - 从 graphql 查询中排除 meta(__type, symbol) 信息
- python - 在 Python 中如何根据用户输入查看特定行
- eclipse - 将目标定义从 Eclipse Neon (4.6) 更改为 Photon (4.8) 后,Eclipse 应用程序启动配置抛出 InjectionException
- html - CSS:如何在图像周围制作一个 60% 一种颜色和 40% 其他颜色的圆圈?
- android - 未找到 LinearLayout - Xamarin 中的 Axml 启动画面(Forms/Android)
- reportviewer - 报表查看器中的列组
- r - 将冗余行名称(变量)作为列并在 R 中的 csv 文件中重新排列所需数据
- vba - 读取数据库并丢失最后一个条目时出现运行时错误 3201