I'm not sure if there's a better way to do this, I assume there should be. Basically I have a component I want to treat as a standalone form control. This control will always have some sort of special validation attached and I would like it to bubble up to the form whenever the component is used.
I've attached a plunker. Is there a way to for the form to be marked invalid if the component/formControl is invalid? I know I could add the validator to the form itself, but I would like to make things easy and more predictable for future use of this component. I'm also open to better ideas of doing this.
@Component({
selector: 'my-app',
template: `
<form [formGroup]="form">
<my-component-control formControlName="myComponent"></my-component-control>
</form>
<div>Form Value: {{form.value | json}}</div>
<div>Form Valid: {{form.valid}}</div>
`,
})
export class App {
constructor(fb: FormBuilder) {
this.form = fb.group({
myComponent: ''
});
}
}
@Component({
selector: 'my-component-control',
template: `
<div>Control Errors: {{control.errors | json}}</div>
<input [formControl]="control">
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => MyComponentComponent),
}
]
})
export class MyComponentComponent implements ControlValueAccessor {
control: FormControl;
onChange: any = () => { };
onTouched: any = () => { };
constructor() {
this.control = new FormControl('', (control) => {
return control.value ? null : {shouldHaveSomething: true};
});
this.control.valueChanges.subscribe((value) => {
this.onChange(value);
this.onTouched();
});
}
writeValue (obj: any): void {
this.control.setValue(obj);
}
registerOnChange (fn: any): void {
this.onChange = fn;
}
registerOnTouched (fn: any): void {
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
throw new Error('Method not implemented.');
}
}
mat-errordirective: github.com/angular/material2/blob/…validproperty on the form itself as I don't wantngSubmitto be triggerable until the form is actually valid. Does that make sense?setErrormethod ofFormControlangular.io/api/forms/AbstractControl#setValue