访问自定义表单控件的有效值 [英] Access valid value of custom form control

查看:22
本文介绍了访问自定义表单控件的有效值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了代表密码表单控件的自定义组件(以下代码已简化).

密码组件 (html)

...<input formControlName="password" type="password"></表单>

密码组件 (ts)

<预><代码>...@成分({选择器:'密码',templateUrl: './password.component.html',styleUrls: ['./password.component.css'],提供者:[{提供:NG_VALUE_ACCESSOR,useExisting: forwardRef(() => PasswordComponent),多:真}]})导出类 PasswordComponent 实现 ControlValueAccessor {密码表格:表格组;onChange =(密码:字符串)=>{ };onTouched = () =>{ };构造函数(){this.passwordForm = new FormGroup({...密码:new FormControl('')});this.passwordForm.valueChanges.subscribe(data => this.onChange(this.value));}获取值():字符串{返回 this.passwordForm.get('password').value;}写值(密码:字符串):无效{this.passwordForm.get('password').setValue(password);this.onChange(this.value);}registerOnChange(fn: any): void { this.onChange = fn;}registerOnTouched(fn: any): void { this.onTouched = fn;}setDisabledState?(isDisabled: boolean): void { }}

我在其他组件中使用它而不是标准输入元素:

...<password formControlName="password"></password></表单>

验证器来自外部形式(它们未在 PasswordComponent 中定义)

this.userForm = fb.group({...密码:['', [Validators.minLength(10), Validators.maxLength(100)]]});

我的问题是:如何从 PasswordComponent 内部获取 元素的有效性?我想根据有效性对其进行风格化.换句话说,我如何从代表此控件的 PasswordComponent 中获取 userForm 的密码"控件的有效性.

解决方案

由于我们无法直接从 DI 系统获取 NgControl 实例,因为我们会收到循环依赖错误.下图显示了如果我们在自定义值访问器中注入 NgControl 会发生这种情况的原因:

现在应该清楚我们有 NgControl ->表单控件名称 ->值访问器 ->CustomValueAccessor ->NgControl 循环依赖

要解决这个问题,您可以利用Injector 来实现:

component.ts

import { NgControl } from '@angular/forms';导出类 PasswordComponent 实现 ControlValueAccessor {...ngControl: ngControl;构造函数(私有注入:注入器){...}ngOnInit() {this.ngControl = this.inj.get(NgControl)}

template.html

{{ ngControl.control.valid }}

Plunker 示例

I created custom component representing password form control (code below is simplified).

PasswordComponent (html)

<form [formGroup]="passwordForm">
  ...
  <input formControlName="password" type="password">
</form>

PasswordComponent (ts)

...
@Component({
  selector: 'password',
  templateUrl: './password.component.html',
  styleUrls: ['./password.component.css'],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => PasswordComponent),
    multi: true
  }]
})
export class PasswordComponent implements ControlValueAccessor {

  passwordForm: FormGroup;
  onChange = (password: string) => { };  
  onTouched = () => { };                  

  constructor() {
    this.passwordForm = new FormGroup({
      ...
      password: new FormControl('')
    });

    this.passwordForm.valueChanges.subscribe(data => this.onChange(this.value));
  }

  get value(): string {
    return this.passwordForm.get('password').value;
  }

  writeValue(password: string): void {
    this.passwordForm.get('password').setValue(password);
    this.onChange(this.value);
  }

  registerOnChange(fn: any): void { this.onChange = fn; } 

  registerOnTouched(fn: any): void { this.onTouched = fn; }

  setDisabledState?(isDisabled: boolean): void { }
}

I use it in other components instead of standard input element:

<form [formGroup]="userForm">
  ...
  <password formControlName="password"></password>
</form>

Validators are coming from outer form (they're not defined inside PasswordComponent)

this.userForm = fb.group({
  ...
  password: ['', [Validators.minLength(10), Validators.maxLength(100)]] 
});

My question is: how can I get <password> element validity from inside PasswordComponent? I would like to stylize it based on validity. In other words how can I get validity of userForm's 'password' control from PasswordComponent that represents this control.

解决方案

As we can't get NgControl instance directly from DI system since we'll get a circular dependency error. The following diagram shows why it happens if we inject NgControl in our custom value accessor:

Now it should be clear that we have NgControl -> FormControlName -> ValueAccessor -> CustomValueAccessor -> NgControl circular dependency

To work around it you can leverageInjector to achieve that:

component.ts

import { NgControl } from '@angular/forms';
export class PasswordComponent implements ControlValueAccessor {
  ...
  ngControl: NgControl;

  constructor(private inj: Injector) {
    ...
  }

  ngOnInit() {
    this.ngControl = this.inj.get(NgControl)
  }

template.html

{{ ngControl.control.valid }}

Plunker Example

这篇关于访问自定义表单控件的有效值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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