I created custom component representing password form control (code below is simplified).
PasswordComponent (html)
As we can't get NgControl
instance directly from DI system since we'll get a circular dependency error. The following diagram shows why it happens if we inject NgControl
in our custom value accessor:
Now it should be clear that we have NgControl -> FormControlName -> ValueAccessor -> CustomValueAccessor -> NgControl
circular dependency
To work around it you can leverageInjector
to achieve that:
component.ts
import { NgControl } from '@angular/forms';
export class PasswordComponent implements ControlValueAccessor {
...
ngControl: NgControl;
constructor(private inj: Injector) {
...
}
ngOnInit() {
this.ngControl = this.inj.get(NgControl)
}
template.html
{{ ngControl.control.valid }}
Plunker Example
One more way to solve this problem is to Remove the NG_VALUE_ACCESSOR from the provider and just inject NgControl. Using the NgControl instance the component will be registered as ValueAccessor.
constructor(
...,
@Optional() @Self() public ngControl: NgControl,
...,
) {
// Setting the value accessor directly (instead of using
// the providers) to avoid running into a circular import.
if (this.ngControl != null) { this.ngControl.valueAccessor = this; }
}