我建立了一些自定义的表单验证指令,这些指令将表单字段与其他属性进行比较。当您更改表单字段的值时,它们非常有用,验证会触发并更新表单字段的有效性。
我遇到的问题是,当我与之进行比较的属性未更改表单验证时,并且与该属性进行比较的表单字段未更改有效性。
我在这里创建了一个示例闪电战。
https://stackblitz.com/edit/angular-t7h2ok
更改第一个字段的值时,如果它与另一个字段相同,则无效,否则,则无效。问题是当我更改另一个字段时,我想确保在更改另一个属性时,第一个表单字段的有效性也得到更新。
答案 0 :(得分:3)
对可能感兴趣的任何人回答我自己的问题。
虽然Powkachu的答案是我在其他地方确实使用过的答案,但我之前已经读过该文章,但是在这种情况下,我的场景要求我将验证属性绑定到具有[box]语法的属性,并且不能使用属性来表示在这种情况下,控件名称的字符串。
我在视图变量中引用了目标输入的ngModel
<input name="value" [(ngModel)]="value" [notEqual]="other" #valueModel="ngModel">
,现在可以通过调用控件的updateValueAndValidity方法来触发验证。
<input name="other" [(ngModel)]="other" (change)="valueModel.control.updateValueAndValidity()">
答案 1 :(得分:2)
我使用this文章来找到解决方案。我正在重用它的一些句子。
首先,将指令也输入到其他输入中:
<input name="other" [(ngModel)]="other" notEqual="value">
然后添加一个名为reverse
的新属性。
<input name="other" [(ngModel)]="other" notEqual="value" reverse="true">
更新指令以使用此新属性:
...
import { Attribute } from '@angular/core';
constructor(
@Attribute('notEqual') public notEqual: string,
@Attribute('reverse') public reverse: string
) {}
private get isReverse()
{
if (!this.reverse) return false;
return this.reverse === 'true' ? true: false;
}
validate(c: AbstractControl): { [key: string]: any }
{
// self value
let v = c.value;
// control value
let e = c.root.get(this.notEqual);
// value not equal
if (e && v === e.value && !this.isReverse) {
return {
notEqual: false
}
}
// value equal and reverse
if (e && v !== e.value && this.isReverse) {
if (e.errors !== null)
delete e.errors['notEqual'];
if (e.errors !== null && !Object.keys(e.errors).length)
e.setErrors(null);
}
// value not equal and reverse
if (e && v === e.value && this.isReverse) {
e.setErrors({ notEqual: false });
}
return null;
}
要使此指令有效,请将输入放入相同的<form>
标记中。最后,html文件将如下所示:
<form>
Value: <input name="value" [(ngModel)]="value" notEqual="other"><br>
Other: <input name="other" [(ngModel)]="other" notEqual="value" reverse="true">
</form>
Here是更新的堆叠闪电战。
答案 2 :(得分:0)
对于任何有兴趣的人来说,更干净的解决方案是在验证器中实现OnChanges并添加以下代码。
onChange: () => void;
ngOnChanges(changes: SimpleChanges): void {
if ('theNameOfYourPropertyToWatch' in changes)) {
if (this.onChange) this.onChange();
}
}
registerOnValidatorChange(fn: () => void): void {
this.onChange = fn;
}
我已经为实现此功能的验证程序实现了ValidatorBase类。这是一堆堆炸弹。