自定义控件中的setValidators,无需Angular中的引用 [英] setValidators in custom control without from reference in Angular

查看:422
本文介绍了自定义控件中的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,则必须更改常规实现.您不能在providers数组中将类注册为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();
}

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

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

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆