angular - 使用 ngrx 进行异步验证
问题描述
我有以下表格,我想从 ngrx 商店中的值进行验证
this.form = new FormGroup({
serviceNr: new FormControl('', {
validators: [Validators.required],
}, [this.doubleServiceNrAsyncValidator()]),
...
});
根据 Angular 文档,我确保我的验证器是有限的
ngOnDestroy(): void {
this.isDestroyed.next(true);
this.isDestroyed.complete();
}
在我的模板中
<mat-error *ngIf="form.get('serviceNr').hasError('existingNr')">
{{ 'GENERAL.ALERTS.ERROR.RESOURCE_ALREADY_EXIST' | translate : { number: this.form.get('serviceNr').value } }}
</mat-error>
我的验证函数如下所示:
doubleServiceNrAsyncValidator = () => (_) => this.store.pipe(select(selectError)).pipe(
takeUntil(this.isDestroyed),
map(err => {
if (err?.errorCode === ErrorCodeEnum.RESOURCE_ALREADY_EXIST) {
return { existingNr: true };
}
if (!!err) {
return { unknown: true };
}
return null;
}),
)
正在调用异步验证器,它返回{ existingNr: true }
正常。但该字段未标记为invalid
解决方案
这种行为是由于您的 observable 从未完成这一事实引起的
this.store.pipe(select(selectError))
,这导致与验证相关联的表单控件处于某种PENDING
状态。虽然formControl
处于这种状态,但不会对其valid
属性应用任何更改。
快速解决方法是在验证器中使用其中一个take(1)
或内部,如下所示:first()
doubleServiceNrAsyncValidator = () => (_) => this.store.pipe(select(selectError)).pipe(
first(),
map(err => {
if (err?.errorCode === ErrorCodeEnum.RESOURCE_ALREADY_EXIST) {
return { existingNr: true };
}
if (!!err) {
return { unknown: true };
}
return null;
}),
操作员将完成源流,这将first
导致 formControl 将所有必要的更改应用于valid
字段
在下面的CodeSandbox 中,我创建了一个并排示例,您和将来的任何人都可能会发现它很有用,因为这是您通常在文档中找不到的情况之一:D
推荐阅读
- java - 如何启用 Saxon xpath 表达式缓存?
- javascript - d3js v5 + Topojson v3 在点击图例上显示/隐藏元素
- javascript - 下划线过滤多维对象
- websocket - Redis vs dynamoDb 地理定位跟踪
- excel - EXCEL VBA Specialcells 读取行
- react-native - React native Expo TypeError:网络请求失败
- r - 重命名R中列表列表中的列
- upgrade - 我正在使用快速 cgi 将 PHP 5.6 升级到 7.2。安装后出现内部服务器错误
- express - sequelize 创建数据库记录后如何从响应中删除 json 元素?
- python - 使用海龟和单击/双击实现 Python tkinter 缩放