本文介绍了自定义控件中的 setValidators 没有来自 Angular 中的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个自定义输入控件.我不想创建任何自定义验证.我想使用默认的必需、minLength、maxLength 等.我知道我可以这样做

i have created a custom input control. I don't want to create any custom validation. I want to use default required, minLength, maxLength etc.I know i can do like this

this.form.controls["firstName"].setValidators([Validators.minLength(1), Validators.maxLength(30)]);

但我无法从父组件发送表单引用.如何在文本框组件中使用 setValidator.

but i can't send form reference from parent component. How can i use setValidator inside textbox component.

// input-box.component.ts
    import { Component, Input, forwardRef } from '@angular/core';
    import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';


    @Component({
      selector: 'app-input-box',
      template:`<label >{{inputdata.label}}</label><br>
      <input type="text" required #textBox [value]="textValue" (keyup)="onChange($event.target.value)" />`,
      styleUrls: ['./input-box.component.less'],
      providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => InputBoxComponent),
          multi: true
        },
        /*{
          provide: NG_VALIDATORS,
          useExisting: forwardRef(() => InputBoxComponent),
          multi: true,
        }*/]
    })
    export class InputBoxComponent implements ControlValueAccessor {
      @Input() inputdata: any;
      private textValue: any = '';

      onChange(value) {
        this.textValue = value;
        this.propagrateChange(value);
      }

      private propagrateChange = (_: any) => { };

      writeValue(value: any) {
        if (this.inputdata.value) {
          this.textValue = this.inputdata.value;
          this.propagrateChange(this.inputdata.value);
        }

      }

      registerOnChange(fn: (value: any) => any) {
        this.propagrateChange = fn;
      }


      registerOnTouched() { }
    }

在不同的组件中使用

<app-input-box  name="textBoxParent_{{index}}"  [inputdata]="goaldata"  ngModel ></app-input-box>

推荐答案

如果您想访问要实现 ControlValueAccessor 的类中的 FormControl,您必须改变你通常的实现.您不能在提供者数组中将该类注册为 ControlValueAccessor 并在构造函数中注入 FormControl.因为 FormControl 会尝试注入你的类,而你会尝试注入控件,这会产生循环依赖.

If you want to access the FormControl inside a class that wants to implement the ControlValueAccessor you have to change your usual implementation. You cannot register the class as ControlValueAccessor in the providers array AND inject the FormControl in the constructor. Because the FormControl will try to inject your class, and you will try to inject the control, which will create a circular dependency.

所以你需要做的改变如下:

So the changes you need to make are as follows:

  1. providers 数组中删除 NG_VALUE_ACCESSORNG_VALIDATORS.
  2. 在构造函数中注入 NgControl 并设置控件的 ControlValueAccessor 和 Validators.

  1. Remove NG_VALUE_ACCESSOR and NG_VALIDATORS from the providers array.
  2. Inject NgControl in the constructor and set the control's ControlValueAccessor and Validators.

constructor(@Self() ngControl: NgControl) {
   ngControl.valueAccessor = this;
   ngControl.setValidators([Validators.minLength(1), Validators.maxLength(30)]
   ngControl.updateValueAndValidity()
}

如果要保留自定义表单组件的使用者指定的验证器,则需要将构造函数修改为:

If you want to keep the validators specified by the consumer of your custom form component you need to modify the constructor to this:

constructor(@Self() ngControl: NgControl) {
  const control = ngControl.control;

  let myValidators = [Validators.required, Validators.minLength(5)];
  let validators = control.validator
  ? [control.validator, ...myValidators]
  : myValidators;

  control.setValidators(validators)
  control.updateValueAndValidity();
}

查看 Kara Erickson(angular core)在 AngularConnect 2017 上解释的整个过程.链接

Check out the whole process explained by Kara Erickson (angular core) at AngularConnect 2017. Link

这篇关于自定义控件中的 setValidators 没有来自 Angular 中的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 02:47