角反应形式-在模糊时验证,但在键入时更新模型

时间:2020-04-01 12:51:17

标签: angular angular-reactive-forms

我遇到了使用反应形式和输入文字的情况。

我需要:

  1. 作为用户类型,根据输入的内容提出一个列表(我正在使用ngx bootstrap typeahead);
  2. 仅当用户失去输入焦点时,才验证输入字段。

为了仅在用户离开输入字段时执行输入验证,我在验证选项中添加了“ updateOn:'blur'”。问题在于,这不仅影响执行验证的时间,还影响模型更新的时间。使用“模糊”功能时,仅当用户离开输入文本时,模型才会更新,结果,由于未更新模型,建议列表无法按用户类型正常工作。

我在stackblitz中添加了一个示例。

我想知道是否有一种方法可以仅在模糊时执行验证,但要根据用户输入的模型进行更新。

谢谢。

2 个答案:

答案 0 :(得分:2)

我不知道执行此操作的任何内置方法,但这是一种方法,它将使用自定义值访问器

custom-input.component.ts

@Component({
  selector: 'app-custom-input',
  template: `
    <p>
      custom input: 
      <input
        #i
        (input)="onChangeFn($event.target.value)" 
        (blur)="onTouchedFn()"
        type="text"
        [formControl]="input"
      >
    </p>

    <p>
    inner input value: {{ i.value }}
    </p>
  `,
  providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: CustomInputComponent, multi: true, } ]
})
export class CustomInputComponent implements OnInit, ControlValueAccessor {
  input: FormControl;
  onTouchedFn: Function;
  onChangeFn: Function;

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.input = this.fb.control('');
  }

  registerOnChange (fn) {
    this.onChangeFn = fn;
  }

  registerOnTouched (fn) {
    this.onTouchedFn = fn;
  }

  writeValue (v) { this.input.setValue(v); }
}

parent.component.ts

  specialInput = new FormControl('', { updateOn: 'blur', validators: Validators.required });

parent.component.html

<app-custom-input [formControl]="specialInput"></app-custom-input>

<p>
  Special input validation status: {{ specialInput.valid || 'false' }}
</p>

您可以将表单控件视为 tree 结构:

FG - FormGroup; FC - FormControl

    FG
 /  |  \
FC  FC  FC

在您的情况下,当FC的值发生更改(例如由于用户输入)时,其所有后代(在这种情况下为FG,但在一个复杂的示例中可能会更多)不论其updateOn的值如何,都可以进行更新。

通过这种方法,这棵 tree 现在看起来像这样(假设最后一个FC是用这种方式构建的):

    FG
 /  |  \_________
FC  FC | FC      |
       |   \     |
       |    FC <-- the `input` elem. in the custom component
       |_________|

因此,值将更新内部onChange 中的FC外部onBlur中的FC < / strong>。

StackBlitz

此外,如果您想了解有关表格的更多信息,建议您查看this article

答案 1 :(得分:0)

我使用了我认为不是最好的解决方案,但是它解决了我当前的问题。

创建表单时,我不再添加验证器,而是添加了一个在模糊执行的函数,该函数将验证器添加到FormControl中,验证并删除验证器;

我可以想象这种解决方案不是理想的解决方案,因为如果我想在除模糊之外的其他时间触发验证,但可能会遇到问题,但是对于我当前的情况来说,它是可行的。

这将是表单的表单创建:

const myInput = new FormControl('', validators: Validators.required })

这是html

<input type="text" (blur)="validate()" formControlName="myInput">

这是验证功能

  validate(): void {
    this.myInput.setAsyncValidators(this.myAsyncValidator());
    this.myInput.updateValueAndValidity();
    this.myInput.clearAsyncValidators();
  }