Подтвердить что ты не робот

Angular2 Стили в директиве

В приведенных примерах директив атрибутов (т.е. директивы для добавления внешнего вида/поведения) мы имеем довольно простую настройку стиля для элемента хоста. Например,

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

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

Вместо того, чтобы устанавливать стиль, могу ли я использовать стили вместо этого? например.

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

Это не работает для меня?

Я делаю что-то более сложное, что привело к большому количеству монолитного кода, установлению множества стилей, использованию AnimationBuilder и т.д. и т.д., мне кажется, что было бы намного лучше отделить это от классов и анимаций в CSS.

ViewEncapsulation = emulated/default, если это важно?

4b9b3361

Ответ 1

Вы можете использовать привязку хоста для привязки к атрибутам стиля:

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

или

@Directive({
    selector: '[myHighlight]',
})
class MyDirective {
  @HostBinding('style.background-color')
  backgroundColor:string = 'yellow';
}

Ответ 2

В то время как другие ответы полезны в большинстве случаев, вам, похоже, нужен более традиционный подход к таблицам стилей CSS, например, у меня был вариант использования.

Проблема заключается в Angular по умолчанию для эмуляции Shadow DOM, который использует стили только внутри элемента хоста.

ДВА ОПЦИИ:

1)

Вы можете сказать Angular каскадировать стили вниз по всем своим потомкам с помощью :host /deep/ .some-style-to-cascade-down-like-normal {} или заменить /deep/ на >>>. См. Angular Docs об этом.

Три важных момента:

  • ViewEncapsulation должно быть по умолчанию (эмулируемым) состоянием
  • Angular/Chrome устаревают оба этих синтаксиса, пока они работают над лучшим подходом
  • Если вы используете CLI Angular, вы должны использовать /deep/ вместо >>>

2)

Хотя вы потеряете инкапсуляцию компонентов с областью (если это имеет значение в вашем случае), вот пример, используя "myHighlight" как директиву, хотя TypeScripted как компонент поэтому я могу импортировать таблицу стилей:

ПРИМЕНЕНИЕ:
<p myHighlight>Highlight me!</p>

TS (компонент рассматривается как директива):

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
})

Angular Материал 2 Кнопка использует этот же подход для решения этой проблемы.

И вот замечательная статья, называемая Все способы добавления CSS в Angular 2 Компоненты, которые привели меня к этому осознанию и объяснили, как Angular обрабатывает все три свойства ViewEncapsulation.

Ответ 3

Я прочитал ваш комментарий ниже первого ответа. Я не знаю, как вы сможете применить свои 30 правил. Но здесь несколько способов - плункер.

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

Ответ 4

Просто создайте элемент, как обычно, используя селектор атрибутов. Создайте файл myHighlight.directive.scss (или любой другой) в той же папке, что и ваша директива, и напишите стили там:

[myhighlight] {
  background-color: yellow;
}

Если ваше приложение не включает ваш файл стиля автоматически, просто импортируйте его в основной файл стиля. Для меня в Ionic 2 он автоматически подбирался.

Если вы хотите использовать определенный класс вместо селектора атрибутов, используйте Renderer для добавления класса.

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);
    }
}

Ответ 5

То же, что и @m.spyratos, но с помощью 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'
    );
  }
}