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

时间:2017-08-06 20:02:27

标签: angular validation angular2-forms

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

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 { }
}

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

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

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

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

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

2 个答案:

答案 0 :(得分:12)

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

enter image description here

现在应该清楚我们有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)
  }

<强> template.html

{{ ngControl.control.valid }}

<强> Plunker Example

答案 1 :(得分:3)

解决此问题的另一种方法是从提供程序中删除NG_VALUE_ACCESSOR并仅注入NgControl。使用NgControl实例,该组件将被注册为ValueAccessor。

L = [ 10, 2, 56, 33, 23, 1, 564, 32, 122, 42, 3, 4, 2, 1, 3, 2, 1, 54, 5, 9, 1, 65, 254 ]

x = int(input("Insert number here: "))

for i in range(0, int(len(L))):
    if L[i] > 100:
       L.pop(i)    
       L.insert(i, x)
       print(L)