import { AfterViewInit , Component , Input , forwardRef } from '@angular/core' ; import { AbstractControl , ControlValueAccessor , FormGroup , NG_VALIDATORS , NG_VALUE_ACCESSOR , ValidationErrors , Validator } from '@angular/forms' ; import { ObParentFormDirective } from './parent-form.directive' ; @ Component ( { selector : 'ob-nested-form' , exportAs : 'obNestedForm' , templateUrl : './nested-form.component.html' , providers : [ { provide : NG_VALUE_ACCESSOR , multi : true , useExisting : forwardRef ( ( ) => ObNestedFormComponent ) } , { provide : NG_VALIDATORS , multi : true , useExisting : forwardRef ( ( ) => ObNestedFormComponent ) } ] , host : { class : 'ob-nested-form' } } ) export class ObNestedFormComponent implements ControlValueAccessor , Validator , AfterViewInit { @ Input ( ) nestedForm : FormGroup ; constructor ( private readonly parent ) { } ngAfterViewInit ( ) { this . parent . submit$ . subscribe ( ( ) => this . nestedForm . markAllAsTouched ( ) ) ; this . parent . reset$ . subscribe ( ( ) => this . nestedForm . reset ( ) ) ; } registerOnChange ( fn ) { this . nestedForm . valueChanges . subscribe ( val => fn ( val ) ) ; } registerOnTouched ( fn ) { } setDisabledState ( isDisabled ) { isDisabled ? this . nestedForm . disable ( ) : this . nestedForm . enable ( ) ; } writeValue ( obj ) { obj ? this . nestedForm . patchValue ( obj ) : this . nestedForm . reset ( ) ; } validate ( control ) { return this . nestedForm . valid ? null : this . formatErrors ( this . nestedForm ) ; } private formatErrors ( form ) { return Object . keys ( form . controls ) . filter ( field => form . get ( field ) . errors ) . reduce ( ( errors , field ) => ( { ... errors , [ field ] : form . get ( field ) . errors } ) , { } ) ; } }