通过自定义控件中的验证,直到将其放置在表单上

时间:2018-09-07 11:45:43

标签: angular angular-material

我创建了一个自定义表单控件,该控件具有一个选择控件,该控件从REST服务中查找其值。在某些情况下,我用从另一个字符串解析的值来预填充控件。我有一个验证,可以检查列表中的值。

这可行,但是当我将控件放在窗体上时,失败的验证不会传递到控件所在的窗体上。

我创建了一个简化的Stackblitz,其中没有该服务。基本选择具有一个简单的“必需”验证器。如果此字段为空白,则提交按钮将被正确禁用。自定义控件具有一个自定义验证器,该验证器会检查未选中“四个”,这会突出显示该字段,但不会禁用提交按钮。 (您可能需要在自定义控件中编辑该值才能开始使用它)

如何将失败的验证从自定义控件传递到包含表单,以使其无效?

2 个答案:

答案 0 :(得分:0)

像这样的自定义控件应该是愚蠢的,即它不会巧妙地从服务本身获取列表并尝试执行自己的验证。这样做可以将逻辑与演示文稿分离开来,Separation of Concerns很好。

一旦验证器在其自己的类中,就可以将其放在包含表单上以在其中提供验证,而无需将错误结果传递到组件之外。

对于验证器“检查值在列表中”的原始问题,从服务中获取其列表的逻辑也需要分离出来,并从包含表单传递给自定义控件。这也使将列表轻松传递到验证器变得容易。

答案 1 :(得分:-1)

如果您使用反应式表单,请尝试避免在模板上使用验证器(必需的max max等...),并使用Validators添加它们。在这种情况下,请尝试从html中删除required并将其添加到ts组件中。

在formGroup中,您可以拥有:

this.formBuilder.group({
   customSelect: 'initialValue',
});

在这种情况下,字段customSelect将具有值'initialValue',这就是您正在使用的

但是您还可以传递一个数组,其中第一个值为您的值,第二个为验证者:

this.formBuilder.group({
   customSelect: ['initialValue', Validators.required]
});

您还可以通过多个验证器:

this.formBuilder.group({
    customSelect: ['initialValue', [Validators.required, OtherValidator]]
});

您还可以检查将是第三个值的异步验证器,以便formGroup在末尾具有以下内容:

[controlState, validators, asyncValidators];

最后,您的组件将具有:

import { Component } from '@angular/core';
import {
  FormBuilder, FormGroup, FormControl, NgControl, ControlValueAccessor, Validators
} from '@angular/forms';

const { required } = Validators;

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
formGroup: FormGroup;

constructor(
  private formBuilder: FormBuilder,
) {
    this.formGroup = this.formBuilder.group({
      customSelect: [[], required],
      baseSelect: [[], required]
    });
    this.oddNumbers();
  }

  oddNumbers() {
    this.formGroup.get('customSelect').setValue(["One", "Three", "Five"]);
    this.formGroup.get('baseSelect').setValue(["One", "Three", "Five"]);
  }

  evenNumbers() {
    this.formGroup.get('customSelect').setValue(["Two", "Four"]);
    this.formGroup.get('baseSelect').setValue(["Two", "Four"]);
  }

  clear() {
    this.formGroup.get('customSelect').setValue(null);
    this.formGroup.get('baseSelect').setValue(null);
  }

} `

您还可以在ngOnInit()上使用一种名为createForm()的方法,而不是在构造函数上添加表单。

ngOnInit() {
    this.createForm();
    this.oddNumbers();
}
createForm() {
    this.formGroup = this.formBuilder.group({
      customSelect: [[], required],
      baseSelect: [[], required]
    });
}