ngxd
ngxd copied to clipboard
ControlValueAccessor
When? ))
Hello,
I implemented a workaround to have this feature implemented and have dynamic forms created at run time by using reactive forms.
I pass the formControl
in the context and set inside the dynamic component on the input.
// parent form
<ng-container
*ngxComponentOutlet="component; context: {formControl: myFormControl};">
</ng-container>
// dynamic component
<app-my-dynamic-component [formControl]="formControl"></alc-my-dynamic-component>
Dynamic CVA can be achieved this way:
@Component({
selector: 'cva-adapter',
template: `
<ng-container
[ngxComponentOutlet]="component"
(ngxComponentOutletActivate)="bind($event)"
></ng-container>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: cvaProviders(CvaAdapterComponent)
})
export class CvaAdapterComponent implements ControlValueAccessor, Validators, OnDestroy {
@Input() public component: any;
public childInstance: ControlValueAccessor<any>;
public onChange: (_: any) => void;
public onTouched: (_: any) => void;
public value: BehaviorSubject<any> = new BehaviorSubject<any>(null);
public registerOnChange(fn: any): void {
this.onChange = fn;
}
public registerOnTouched(fn: any): void {
this.onTouched = fn;
}
public writeValue(obj: any): void {
this.value.next(obj);
}
public validate(): ValidationErrors | null {
return this.childInstance ? this.childInstance.validate() : null;
}
public setDisabledState(isDisabled: boolean): void {
if (this.childInstance?.setDisabledState) {
this.childInstance.setDisabledState(isDisabled);
}
}
public bind(childInstance: ControlValueAccessor<any>) {
this.childInstance = childInstance;
this.childInstance.registerOnChange(this.onChange);
this.childInstance.registerOnTouched(this.onTouched);
this.value.pipe(
takeUntil() // Don't forget to unsubscribe
).subscribe(value => {
this.childInstance.writeValue(value);
});
}
ngOnDestroy(): void {
this.childInstance = undefined;
}
}
Hey @zvnt! I have working example with dynamic forms here https://stackblitz.com/edit/angular-form-builder-lcsabo?file=src%2Fapp%2Fdynamic-field%2Fdynamic-field.component.ts
AutoCVA
is @thekiba `s approach to reduce cva interface boilerplate