我必须创建一个带有自定义输入元素的组件(以及组件内部的更多元素,但这不是问题而不是此处示例的一部分)组件内外的强>反应/模型驱动方法和验证。
我已经创建了组件,它运行正常,我的问题是formControl(在子级和父级内)在验证或触摸状态时都不同步。例如,如果键入的字符串超过10个字符,则表单内的表单控件将是stil有效。
//our root app component
import {Component, Input} from '@angular/core'
import {
FormControl,
FormGroup,
ControlValueAccessor,
NG_VALUE_ACCESSOR,
Validators
} from '@angular/forms';
@Component({
selector: 'my-child',
template: `
<h1>Child</h1>
<input [formControl]="childControl">
`,
providers: [
{provide: NG_VALUE_ACCESSOR, useExisting: Child, multi: true}
]
})
export class Child implements ControlValueAccessor {
childControl = new FormControl('', Validators.maxLength(10));
writeValue(value: any) {
this.childControl.setValue(value);
}
registerOnChange(fn: (value: any) => void) {
this.childControl.valueChanges.subscribe(fn);
}
registerOnTouched() {}
}
@Component({
selector: 'my-app',
template: `
<div>
<h4>Hello {{name}}</h4>
<form [formGroup]="form" (ngSubmit)="sayHello()">
<my-child formControlName="username"></my-child>
<button type="submit">Register</button>
</form>
{{form.value | json }}
</div>
`
})
export class App {
form = new FormGroup({
username: new FormControl('username', Validators.required)
});
constructor() {
this.name = 'Angular2';
}
sayHello() {
console.log(this.form.controls['username'])
}
}
我不知道如何以正确的方式解决这个问题
答案 0 :(得分:0)
存在来自Angular的Validator接口,用于将验证转发给父级。您需要使用它,并使用forwardRef将NG_VALIDATORS提供给组件装饰器的providers数组:
{
provide: NG_VALIDATORS,
useExisting: CustomInputComponent,
multi: true
}
您的组件需要实现Validator接口:
class CustomInputComponent implements ControlValueAccessor, Validator,...
,并且您必须提供Validator接口的方法的实现,至少是validate方法的实现:
validate(control: AbstractControl): ValidationErrors | null {
return this.formGroup.controls['anyControl'].invalid ? { 'anyControlInvalid': true } : null;
}
当输入更改时,还有另一个同步验证器:
registerOnValidatorChange(fn: () => void): void {
this.validatorChange = fn;
}