Emre HIZLI
Emre HIZLI

Reputation: 520

How to use my own custom directive on my component in angular 4 and above

I want use like this:

<v-button uppercase>test</v-button>

my component and directive as follows:

@Component({
    selector: "v-button",
    template: "<button class="if component has uppercase directive set 'uppercase css class' here"></button>"
})
export class ButtonComponent{
}

@Directive({
   selector : "[uppercase]"
})
export class UppercaseDirective{
}

and i expect this:

<button class="uppercase">test</button>

thanks for helps.

Solution : for thank you @Wand Maker for giving me the tip

@Component({
selector: "v-button",
template: "<button #uppercaseFlag class="if component has uppercase directive set 'uppercase css class' here"></button>"
})
export class ButtonComponent{
 @ViewChild('uppercaseFlag') uppercaseElement: ElementRef;
}

@Directive({
 selector : "[uppercase]",
 providers : [ButtonComponent]
})
export class UppercaseDirective{
 ngAfterContentInit(): void {
 this.renderer.addClass(this.button.uppercaseElement.nativeElement, "uppercase");
 }
 constructor(private readonly renderer: Renderer2, private readonly button: ButtonComponent) { }
 }

Upvotes: 0

Views: 481

Answers (1)

Wand Maker
Wand Maker

Reputation: 18762

The directive needs to access the button child and add class attribute to it. To do that, you can inject ElementRef in directive constructor to obtain reference to host element v-button, and then, wait for the component to get initialized - after which in ngAfterContentInit method - you can assign uppercase style to first child of v-button - which will be a button element. If you do change template of v-button, you may have to adjust this part of the code.

Here is the directive code:

@Directive({
   selector : "[uppercase]"
})
export class UppercaseDirective implements  AfterContentInit {
  constructor(private el: ElementRef) {
  }

  ngAfterContentInit() {
    this.el.nativeElement.children[0].className='uppercase';
  }
}

In addition, you may also want to update your v-button template to have ng-content so that buttons can be assigned a text/name like this:

 <v-button uppercase>Test</v-button>

Here is updated component code:

@Component({
    selector: "v-button",
    template: "<button><ng-content></ng-content></button>"
})
export class ButtonComponent{
}

Upvotes: 1

Related Questions