Angular2 Styles in a Directive

Viewed 59672

In the given examples of Attribute directives (i.e. a directive to add appearance/behaviour), we have a fairly simple setting of a style on the host element.. e.g.

import {Directive, ElementRef } from 'angular2/core';
@Directive({
    selector: '[myHighlight]'
})
export class HighlightDirective {
    constructor(element) {
       element.nativeElement.style.backgroundColor = 'yellow';
    }

static get parameters(){
    return [[ElementRef]];
}

Rather than setting the style, can i use a styles instead? e.g.

@Directive({
    selector: '[myHighlight]',
    styles: [':host { background-color: yellow; }']
})

This doesn't seem to work for me?

I'm doing something slightly more complex which has led to a fair amount of monolothic code, setting lots of styles, using AnimationBuilder etc etc. feels to me like it would be much better to seperate this out into classes and animations in a CSS.

ViewEncapsulation = emulated/default if that matters?

6 Answers

It's too late for this answer but has used one tricky solution in my same kind of requirement so i feel it may help someone.

I did it in the following way and it worked for me

<div class="someClass" customDirective>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>

import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[customDirective]'
})
export class CustomDirective {
  domElement: any;

  constructor(private elementRef: ElementRef) {
  this.domElement = this.elementRef.nativeElement;
  const newStyles = {
     'background-color': 'yellow',
     'color': 'red',
     'font-weight': 'bold',
     //...and so on
    };
   Object.keys(newStyles).forEach(element => {
     this.domElement.style.setProperty(`${element}`,newStyles[element]);
    }      

  } 
//Other logic required for the directive...

}

Working Example

Same as @m.spyratos, but using Renderer2:

import {
  Directive,
  ElementRef,
  OnInit,
  Renderer2
} from '@angular/core';

@Directive({
  selector: '[myButton]'
})
export class MyButtonDirective implements OnInit {
  constructor(
    private elementRef: ElementRef,
    private renderer: Renderer2
  ) { }

  public ngOnInit(): void {
    this.renderer.addClass(
      this.elementRef.nativeElement,
      'my-button'
    );
  }
}

Just style the element as you would do normally using the attribute selector. Create a myHighlight.directive.scss (or whatever) file in the same folder as your directive and write your styles in there:

[myhighlight] {
  background-color: yellow;
}

If your app doesn't include your style file automatically, just import it in your main style file. For me in Ionic 2 it was picked up automatically.

If you want to use a specific class instead of the attribute selector, then use the Renderer to add the class.

import {Directive, ElementRef, Renderer} from 'angular2/core';
@Directive({
    selector: '[myHighlight]'
})
export class HighlightDirective {
    constructor(private el: ElementRef, private renderer: Renderer) {
        this.renderer.setElementClass(this.el.nativeElement, 'my-highlight', true);
    }
}
Related