我的验证器告诉“无效”,即使实际上不是

时间:2018-11-07 09:55:55

标签: angular typescript validation

我当前正在创建一个文本字段,该字段不应为空,也不应以特定的字符链开头。 (让我们说“测试”)

例如我希望testxyz无效,而其他任何有效。我已经有了RegExp:/^((?!(test)).)*$/gmi。我知道类似abctest的内容也是无效的,但这与这种情况无关紧要。

问题是,每当我输入的字符数为偶数(!)的字符串时,一旦提交了无效的输入,验证器就会说这是无效的输入(打印“错误2”;您可以看到从哪里得到错误)以HTML格式打印),即使事实并非如此!

例如如果我先写test,它会给我一个错误,指出它无效。正确。如果我再写任何字符,例如a,则不会出现错误。也正确。但是,一旦我写了偶数个字符,无论是什么(!),例如aawxyz,它都会给我一个错误,在不应该的地方!

我仍然可以提交它,并且一切正常,这只是验证程序的错误“解释”,我不知道他为什么这样做。也许有人可以帮助我。我在下面添加了代码。

HTML:

<h1 mat-dialog-title>{{data.dialogTitle}}</h1>
<div mat-dialog-content>
  <p class="mat-typography">{{data.dialogText}}</p>
</div>

<mat-form-field>
  <input matInput [(ngModel)]="name" placeholder="Enter your name?" [formControl]="InputControl">
  <mat-error *ngIf='InputControl.hasError("required")'>
    Error 1
  </mat-error>
  <mat-error *ngIf='InputControl.hasError("pattern")'>
    Error 2
  </mat-error>
</mat-form-field>

<mat-dialog-actions>
  <span style="flex: 1 1 auto"></span>
  <button mat-flat-button (click)="pressed()" class="mat-primary">OK</button>
</mat-dialog-actions>

TypeScript:

export class DialogComponent {

    regExp = /^((?!(test)).)*$/gmi;
    InputControl = new FormControl("", [Validators.required, Validators.pattern(this.regExp)])
    @Input() name:string

    constructor(public dialogRef: MatDialogRef<DialogComponent>,
                @Optional() @Inject(MAT_DIALOG_DATA) public data: any) { }

    pressed() {
        console.log(this.name.match(this.regExp));
        if(this.regExp.test(this.name)) {
            alert("valid");
            this.dialogRef.close(true);
        }
    }
}

谢谢。

2 个答案:

答案 0 :(得分:2)

根本原因在于执行上下文。在Validators.pattern函数中,您是通过this.regExp引用它的参数的,但是此函数不会在当前控制器的范围内执行,因此this不会指向您的控制器,但是在这种情况下使用InputControl类的某些Angular内部函数。因此,简单地说,您输了this

要快速而肮脏的解决方案更改:

Validators.pattern(this.regExp)  

收件人:

Validators.pattern(/^((?!(test)).)*$/gmi)

并确认是否有帮助。

如果是,那么,如果您仍然希望将模式存储在控制器中,则基本上必须将验证器函数包装在另一个控制器函数中,以将模式封装在闭包中,这将在执行上下文中可用:

getMyValidation(): (AbstractControl): ValidationErrors | null {
  let pattern = this.regExp;
  return Validators.pattern(pattern)
}

并将其传递给表单构造函数,如下所示:

InputControl = new FormControl("", [Validators.required, this.getMyValidation()])

答案 1 :(得分:0)

好的,显然我是一个人发现了错误。这与我使用的标志有关。 gmi

我删除了“ g”,现在可以使用了。我认为这与RegExp对象的工作方式有关。当您使用'g'标志时,该对象会跟踪发生匹配的lastIndex,因此在随后的匹配中它将从那里开始。如果删除“ g”标志,则在比赛后基本上将其设置为零,从而解决了我的问题。 但是,我不确定100%。