0

I have a component which is meant to wrap Reactive Form controls. I want to standardize those controls, requiring minimun amount of client code and injecting stuff like custom CSS classes.

At the same time, I don't want to force clients to add yet another directive to control elements. Hence, I would like to hook into elements that already use the FormControlName directive.

Here's what I want my client code to look like:

<my-form-control>
  <input formControlName="whatever" />
</my-form-control>

And here's what my component looks like so far:

import { Component, AfterContentInit, Input, ContentChild, Renderer2 } from '@angular/core';
import { FormControlName } from '@angular/forms';

@Component({
  selector: 'my-form-control',
  template: `<ng-content select="[formControlName]"></ng-content>`
})
export class MyFormControlComponent implements AfterContentInit {
  @ContentChild(FormControlName, {static: false}) directive: FormControlName;

  constructor(private renderer: Renderer2) {}

  ngAfterContentInit() {
    // Ok, I have the directive. Now I need access to
    // the native element somehow to add the class like so:
    const nativeElement = this.directive.<<< GRAB_ELEMENT_SOMEHOW??? >>>();
    this.renderer.addClass(nativeElement, 'my-control');
  }
}

I've put together a StackBlitz of what I'm trying to do:

Charles
  • 1,118
  • 13
  • 23

1 Answers1

1

All you need to do is to add read option to your ContentChild decorator:

@ContentChild(FormControlName, {static: false, read: ElementRef }) directive: ElementRef;

..
ngAfterContentInit() {
  const nativeElement = this.directive.nativeElement;
  this.renderer.addClass(nativeElement, 'my-control');
}

Forked Stackblitz

See also:

yurzui
  • 205,937
  • 32
  • 433
  • 399