访问自定义表单控件的有效值

Wil*_*nik 8 validation angular2-forms angular

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

PasswordComponent(html)

<form [formGroup]="passwordForm">
  ...
  <input formControlName="password" type="password">
</form>
Run Code Online (Sandbox Code Playgroud)

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 { }
}
Run Code Online (Sandbox Code Playgroud)

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

<form [formGroup]="userForm">
  ...
  <password formControlName="password"></password>
</form>
Run Code Online (Sandbox Code Playgroud)

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

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

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

yur*_*zui 12

因为我们无法NgControl直接从DI系统获取实例,因为我们将得到循环依赖性错误.下图显示了为什么在我们注入NgControl自定义值访问器时会发生这种情况:

在此输入图像描述

现在应该清楚我们有NgControl -> FormControlName -> ValueAccessor -> CustomValueAccessor -> NgControl循环依赖

要解决它,您可以利用它Injector来实现:

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)
  }
Run Code Online (Sandbox Code Playgroud)

template.html

{{ ngControl.control.valid }}
Run Code Online (Sandbox Code Playgroud)

Plunker示例