Last active
August 2, 2021 12:09
-
-
Save Dyljyn/59e95fbe09a24b1835667a1a5e401e5a to your computer and use it in GitHub Desktop.
Syncing reactive form controls - Angular (v6)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
Directive, | |
EventEmitter, | |
InjectFlags, | |
Injector, | |
OnDestroy, | |
OnInit, | |
Type | |
} from '@angular/core'; | |
import { AbstractControl, FormControlDirective, FormControlName } from '@angular/forms'; | |
import { takeUntil } from 'rxjs/operators'; | |
const formDirectives = [FormControlName, FormControlDirective]; | |
@Directive({ | |
selector: '[syncControl]' | |
}) | |
export class SyncControlDirective implements OnInit, OnDestroy { | |
private readonly directiveDestroyed$ = new EventEmitter<void>(); | |
constructor(private injector: Injector) {} | |
ngOnDestroy() { | |
this.directiveDestroyed$.emit(); | |
this.directiveDestroyed$.complete(); | |
} | |
ngOnInit() { | |
const control = this.getControl(); | |
if (!control) { | |
return; | |
} | |
control.valueChanges | |
.pipe(takeUntil(this.directiveDestroyed$)) | |
.subscribe(value => { | |
control.setValue(value, { emitEvent: false }); | |
}); | |
} | |
getControl(): AbstractControl { | |
let foundDirective; | |
for (const directive of formDirectives) { | |
foundDirective = this.getDirective(directive); | |
if (foundDirective) { | |
return foundDirective.control; | |
} | |
} | |
return undefined; | |
} | |
private getDirective<T extends Type<any>>(directive: T): T | undefined { | |
return this.injector.get( | |
directive, | |
// setting 'notFoundValue' to 'undefined' will make the method throw an error | |
null, | |
InjectFlags.Optional | InjectFlags.Self | |
) || undefined; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment