将值与更改进行比较时,如何触发Angular验证指令进行更新?

时间:2018-09-06 05:07:51

标签: angular

我建立了一些自定义的表单验证指令,这些指令将表单字段与其他属性进行比较。当您更改表单字段的值时,它们非常有用,验证会触发并更新表单字段的有效性。

我遇到的问题是,当我与之进行比较的属性未更改表单验证时,并且与该属性进行比较的表单字段未更改有效性。

我在这里创建了一个示例闪电战。

https://stackblitz.com/edit/angular-t7h2ok

更改第一个字段的值时,如果它与另一个字段相同,则无效,否则,则无效。问题是当我更改另一个字段时,我想确保在更改另一个属性时,第一个表单字段的有效性也得到更新。

3 个答案:

答案 0 :(得分:3)

对可能感兴趣的任何人回答我自己的问题。

虽然Powkachu的答案是我在其他地方确实使用过的答案,但我之前已经读过该文章,但是在这种情况下,我的场景要求我将验证属性绑定到具有[box]语法的属性,并且不能使用属性来表示在这种情况下,控件名称的字符串。

我在视图变量中引用了目标输入的ngModel

<input name="value" [(ngModel)]="value" [notEqual]="other" #valueModel="ngModel">

,现在可以通过调用控件的updateValueAndValidity方法来触发验证。

<input name="other" [(ngModel)]="other" (change)="valueModel.control.updateValueAndValidity()">

这是一堆https://stackblitz.com/edit/angular-9fnsmz

答案 1 :(得分:2)

我使用this文章来找到解决方案。我正在重用它的一些句子。

首先,将指令也输入到其他输入中:

<input name="other" [(ngModel)]="other" notEqual="value">

然后添加一个名为reverse的新属性。

<input name="other" [(ngModel)]="other" notEqual="value" reverse="true">
  • 当反向设置为 false 未设置时,我们将执行notEqual验证。
  • 当reverse为 true 时,我们仍将执行notEqual,但我们不会向当前控件添加错误,而是向目标控件添加错误。

更新指令以使用此新属性:

...
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类。这是一堆堆炸弹。

https://stackblitz.com/edit/angular-cfexiy