表单生成器-无法读取未定义的属性“ get”,验证程序存在问题

时间:2018-10-23 12:19:14

标签: javascript angular forms angular6 formbuilder

我的Angular 6项目中有一个Form Builder表单,但验证程序出现问题。

我想我知道问题是什么,但不知道如何解决。 我有一个自定义验证器(不是真正的自定义器,我使用min()和max()以及用于检查的自定义变量)

可能表单在这些值之前被初始化。

该表单在构造函数之前声明(我尝试将其移入构造和ngOnInit,结果相同)

myForm = this.fb.group({
        title: [""],
        date: [""],
        max_score: [, [Validators.required, Validators.max(6), Validators.min(1)]],
        min_score: [, [Validators.required, Validators.max(6), Validators.min(1)]]
});

constructor(private fb: FormBuilder) {}

像这样,即使验证程序也可以正常工作。 max_scoremin_score是2个下拉菜单,您可以在其中选择一个数字。

我想实现的是这样:

max_score: [, [Validators.required, Validators.max(6), Validators.min(this.myForm.get("min_points").value)]],
min_score: [, [Validators.required, Validators.max(this.myForm.get("max_score").value), Validators.min(1)]]

因此,基本上max_score不能低于min_score,并且min_score不能高于max_score

但这给了我错误:

TypeError: Cannot read property 'get' of undefined

所以我想这是因为在初始化“表单”构建器时无法访问this.myForm.get("max_score").value

我该如何解决?这些值在我的表单中是可选的,因此在开始时就没有值是正确的,我只想进行检查以避免选择的min_value大于max_value

我什至尝试将this.myForm.get ....放在函数中:

getMaxPoints(): number {
        if (this.myForm.get("max_score").value) {
            return this.myForm.get("max_score").value;
        } else return null;
    }

然后

 min_score: [, [Validators.required, Validators.max(this.getMaxPoints()), Validators.min(1)]]

但是我遇到同样的错误!

此问题的解决方法是什么?

3 个答案:

答案 0 :(得分:0)

创建表单时,将值传递给验证器数组,这些值仅在创建时传递。

因此,如果您使用

这样的表达式
Validators.max(this.myForm.get("max_points").value)

您正在创建表单时进行评估。因此myForm变量仍未定义。

尝试使用一些变量,而不是像这样访问myForm属性:

minVal: number = 5;
maxVal: number = 5;

max_score: [, [Validators.required, Validators.max(6), Validators.min(minVal)]],
min_score: [, [Validators.required, Validators.max(maxVal), Validators.min(1)]]

要验证从表单中获取一些参数的数据,您应该使用this.fb.group()

中的额外内容

您可以尝试以下操作:

myForm = this.fb.group({
        title: [""],
        date: [""],
        max_score: [, [Validators.required]],
        min_score: [, [Validators.required]]
},
{
       // THIS IS EXTRA!!!!!
       validator: [customValidator()]
});

这是customValidator的示例:

export function customValidator() {
  return (group: FormGroup) => {
    const minScore = group.controls['min_score'],
      maxScore = group.controls['max_core'],
      minPoints = group.controls['min_points'];

    if (/** some condition **/) {
      return minPoints.setErrors({'notMatching': true});
    } else {
      return minPoints.setErrors(null);
    }
  };
}

请注意,您正在customValidator中以动态方式访问myForm数据,以访问其控件。

然后您需要在模板中显示错误,具体取决于

<div *ngIf="f.min_points.errors && f.min_points.errors.notMatching">NOT VALID</div>

我不记得是否存在notMatching错误,但是您可以使用

打印所有可用错误
<pre>{{ f.min_points.errors | json }</pre>

其中f是这样的便捷获取方法:

 get f() {
    return this.myForm.controls;
  }

答案 1 :(得分:0)

应该是:

public myForm:FormGroup; // you should do this
constructor(private fb: FormBuilder) {
     this.myForm = this.fb.group({
        title: [''],
        date: [''],
        max_score: ['', [Validators.required, Validators.max(6), Validators.min(1)]],
        min_score: ['', [Validators.required, Validators.max(6), Validators.min(1)]]
     });
}

并访问它:

this.myForm.get("max_score").value

或:

this.myForm.controls["max_score"].value

答案 2 :(得分:0)

您可以在html中的最小和最大两个位置添加一个(keyup)="checkMinMax()"。在checkMinMax函数中,您可以检查this.myForm.get("max_score").valuethis.myForm.get("min_score").value的内容,或者显示带有* ngIf的消息,如注释中提到的那样,或者如果最小值或最大值与其他值相同,则将其强制相同用户的输入超出此范围。 ( 或两者 )。

此外,您还可以使用所需的验证器。