web-dev-qa-db-fra.com

Styles Angular2 dans une directive

Dans les exemples donnés de directives d'attribut (c'est-à-dire une directive pour ajouter une apparence/un comportement), nous avons un paramètre assez simple pour un style sur l'élément Host.

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

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

Plutôt que de définir le style, puis-je utiliser un style? par exemple.

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

Cela ne semble pas fonctionner pour moi?

Je fais quelque chose de légèrement plus complexe qui a conduit à beaucoup de code monolothique, à la définition de nombreux styles, à l'utilisation d'AnimationBuilder etc.

ViewEncapsulation = émulé/par défaut si cela compte?

36
ct5845

Vous pouvez utiliser la liaison hôte pour lier des attributs de style:

@Directive({
    selector: '[myHighlight]',
    Host: {
      '[style.background-color]': '"yellow"',
    }
})

ou

@Directive({
    selector: '[myHighlight]',
})
class MyDirective {
  @HostBinding('style.background-color')
  backgroundColor:string = 'yellow';
}
38
Günter Zöchbauer

Alors que les autres réponses sont utiles dans la plupart des cas, vous semblez avoir besoin d'une approche de feuille de style CSS plus traditionnelle, comme celle que j'avais auparavant.

Le problème est celui d'Angular qui émule par défaut un DOM Shadow qui étend les styles uniquement dans l'élément Host.

DEUX OPTIONS:

1)

Vous pouvez dire à Angular de faire passer vos styles en cascade par l’ensemble de ses descendants à l’aide de la touche :Host /deep/ .some-style-to-cascade-down-like-normal {} _ ou remplacer /deep/ avec >>>. Voir Docs Angular à ce sujet.

Trois points importants à noter:

  • ViewEncapsulation doit être son état par défaut (émulé)
  • Angular/Chrome déconseillent ces deux syntaxes alors qu’elles travaillent à une meilleure approche
  • Si vous utilisez le CLI Angular, vous devez utiliser le /deep/ au lieu de >>>

2)

Bien que vous perdiez l'encapsulation du composant concerné (si cela compte dans votre cas), voici un exemple utilisant "myHighlight" comme directive quoique Tapez comme un composant pour importer la feuille de style:

USAGE:
<p myHighlight>Highlight me!</p>

TS (composant traité comme un directive):

import {
    Component,
    ViewEncapsulation
} from '@angular/core';

@Component({
    selector: 'p[myHighlight]', // Refer to it like an attribute directive
    templateUrl: './my-highlight.component.html',
    styleUrls: ['./my-highlight.component.scss'],
    encapsulation: ViewEncapsulation.None // Tell Angular to not scope your styles
})

Bouton du matériau angulaire 2 utilise cette même approche pour résoudre ce problème.

Et voici un excellent article intitulé Toutes les manières d’ajouter CSS à Angular 2 composants qui m’a amené à cette prise de conscience et explique comment Angular = traite les trois propriétés de ViewEncapsulation.

18
bit-less

J'ai lu votre commentaire ci-dessous première réponse. Je ne sais pas comment pourriez-vous appliquer vos 30 règles. Mais peu de voies sont ici-plunker .

selector:"[myHighlight]", 
    Host: {        
    '(mouseenter)':'changeColor()',
    '[style.background]': '"pink"', 
    '(click)':'clickMe()',
    '(mouseout)':'changeColorOnOut()',
  }
4
micronyks

Identique à @ m.spyratos, mais en utilisant 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'
    );
  }
}
2
Steve Brush

Style juste l'élément comme vous le feriez normalement en utilisant le sélecteur d'attribut. Créer un myHighlight.directive.scss (ou autre) dans le même dossier que votre directive et écrivez vos styles dans ce fichier:

[myhighlight] {
  background-color: yellow;
}

Si votre application n'inclut pas automatiquement votre fichier de style, importez-le simplement dans votre fichier de style principal. Pour moi, dans Ionic 2, il a été capté automatiquement.

Si vous souhaitez utiliser une classe spécifique au lieu du sélecteur d'attribut, utilisez le moteur de rendu pour ajouter la classe.

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);
    }
}
0
m.spyratos