Angular2 - 使用旧数据的自定义验证器
Posted
技术标签:
【中文标题】Angular2 - 使用旧数据的自定义验证器【英文标题】:Angular2 - Custom validator using old data 【发布时间】:2017-06-28 23:18:28 【问题描述】:我编写的自定义验证器有问题。验证器用于验证组件中的所有数据。
设置如下:
组件显示一个包含 X 行数据的表格。一些行是仅显示模式,而其他行将处于编辑模式(表中的某些单元格将具有输入、选择等)。支持表格的是一个数据对象数组(tableData)。
如果一行处于编辑模式,则每个输入都双向绑定到 tableData 数组中的相应元素。
我的自定义验证器应用于表单标签并将 tableData 作为输入。一切大部分都有效。验证数据查看表中的每一行,并完成我需要做的所有事情。
问题是基于我的自定义验证器的数据是旧数据。因此,如果一行处于编辑模式,当我更改选择中的值时,tableData 会更新,但传递给验证器的版本是在更新之前。所以我总是在验证旧版本的 tableData。
我不确定如何获得验证以使用最新版本的 tableData。我认为这个问题可能与 select 绑定更改了 tableData 数组中对象的值有关,但 tableData 数组本身实际上并没有改变。
我尝试将回调添加到正在编辑的行中选择的(更改)事件。调用(更改)的方法使用 ChangeDetectorRef 手动触发更改检测,但这不起作用。
我不想用所有的整个文件向每个人发送垃圾邮件,所以我尝试只添加重要的 sn-ps。
这是模板:
<form #f="ngForm" novalidate custom-validator="tableData | json">
<p-dataTable [value]="tableData">
...
<p-column [header]="'Program Name'">
<template let-row="rowData" let-idx="rowIndex" pTemplate type="body">
<span *ngIf="!row['edit']">
row['data'].programName
</span>
<div *ngIf="row['edit']">
<select #progName="ngModel" [(ngModel)]="row['data'].programCode"
title="Select Program" required (change)="onProgramChange($event, idx)"
name="programSelect-idx">
<option [value]=""></option>
<option *ngFor="let prog of programList" [value]="prog.code">
prog.name
</option>
</select>
</div>
</template>
</p-column>
...
</p-dataTable>
</form>
这是支持组件:
//imports...
...
private tableData: PersonAssignmentRowData[] = [];
private programList: Program[] = [];
...
onProgramChange(event: any, index: number)
for(let prog of this.programList)
if(prog.code == event.target.value)
this.tableData[index].data.programAcronym = prog.acronym;
this.tableData[index].data.programLocation = prog.location;
this.tableData[index].data.programName = prog.name;
break;
...
这是验证器:
@Directive(
selector: '[custom-validator]',
providers:[provide: NG_VALIDATORS, useExisting: CustomValidator, multi: true]
)
export class CustomValidator implements Validator
@Input('custom-validator') tableDataString: string;
validate(control: AbstractControl)
if(this.tableDataString == null || this.tableDataString.length == 0)
return null;
let tableData: PersonAssignmentRowData[] = [];
tableData = JSON.parse(this.tableDataString);
let message: string = '';
//logic that tests the validity of the data and sets any error messages in the message variable
if(message.length > 0)
return 'validationMessage': message;
else
return null;
【问题讨论】:
没有代码就不可能弄清楚它有什么问题。 我已经用代码更新了我的问题。 【参考方案1】:现在很清楚了。当然它不会起作用。验证器应该检查的唯一数据源是传递给 validate() 方法的控件。没有 @Inputs() 或任何类似的东西。唯一的区别是下面的 control.value 将包含表单中所有控件的所有值,而不仅仅是您的表格,因此您应该在表格所在的位置选择正确的嵌套值。
@Directive(
selector: '[custom-validator]',
providers:[provide: NG_VALIDATORS, useExisting: forwardRef(() => CustomValidator), multi: true]
)
export class CustomValidator implements Validator
validate(control: AbstractControl)
tableData = control.table.value; // need to figure out exact path based on your form structure
let message: string = '';
//logic that tests the validity of the data and sets any error messages in the message variable
if(message.length > 0)
return 'validationMessage': message;
return null;
【讨论】:
我见过其他接受输入的验证器。我遇到的问题是我需要验证不在控件中的数据,因此我将支持对象作为输入传递。 那是错误的。如果您的数据不受控制,那么您需要这样做,而不是通过其他方式传递数据。以上是关于Angular2 - 使用旧数据的自定义验证器的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 Angular 2 中的自定义验证规则显示错误消息?
Angular 2 / Material - 应用到父 FormGroup 的自定义验证器未显示 md 错误