enyo
enyo

Reputation: 16726

How to access NgFormControl in custom Ng2 form element

I wrote my own custom form element DateInputComponent by implementing ControlValueAccessor and use it like this:

<my-date-input ngControl="date"></my-date-input>

From what I understand, ngControl is syntactic sugar for [ngFormControl]="myControlGroup.controls['date']".

Now, inside my DateInputComponent I would like to access the NgFormControl.

I tried to bind it with @Input NgFormControl ngFormControl; but it never gets set, and I tried injecting it with DateInputComponent(NgFormControl ngFormControl) but that fails because there is no provider.

What is the correct approach to get it?

(Maybe I'm also approaching it the wrong way... I'd like for this DateInputComponent to be able to display all validation errors by itself that might occur.)

Upvotes: 1

Views: 816

Answers (2)

enyo
enyo

Reputation: 16726

I got it to work with the solution this comment suggest: by injecting the Injector and reading the NgControl out of it:

class DateInputComponent implements ControlValueAccessor, AfterViewInit {
  Injector _injector;
  DateInputComponent(this._injector);

  NgControl control;

  @override
  ngAfterViewInit() {
    control = _injector.get(NgControl).control;
  }
}

Directly injecting the NgControl, as Ted suggested, doesn't work, because it causes a cyclic dependency.

Trying to access the NgControl in the constructor won't work, because it's not available yet.

Upvotes: 1

Ted Sander
Ted Sander

Reputation: 1899

You are on the right approach with injecting the directive, but the problem is while ngControl could be considered syntactic sugar for NgFormControl it isn't the same class.

All of the form controls extend from NgControl and this is what you should be injecting into your component. DateInputComponent(NgControl ngControl)

All the form directives are meant to work interchangeably so they all provide NgControl as the interface they are exposing. This allows the user of your date component to use whatever directive works for their use case:

  • NgModel: if they just want provide or listen to the value
  • NgFormControl: if they want to provide the control
  • NgControlName: if they want to use the string identifier into the ControlMap (This is the one you are using above)

Upvotes: 1

Related Questions