2016-03-10 2 views
23

В приведенных примерах директив атрибутов (т. Е. Директивы для добавления внешнего вида/поведения) мы имеем довольно простую настройку стиля для элемента-хозяина.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, если это важно?

+0

Хотя это был год, ради потомства, я добавил ответ ниже. Он включает как использование компонента в качестве директивы, так и изменение стандартного ViewEncapsulation. См. Мой ответ ниже. - Приветствия –

ответ

20

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

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

или

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

Спасибо, но это все еще оставляет мне вопрос о необходимости устанавливать n количество свойств по отдельности, а не использовать встроенный/внешний CSS? Это хорошо в этом простом примере, но что, если у меня есть 30+ правил с анимацией, и эти правила могут применяться в разных состояниях/комбинациях, например. зависания, клики и т. д. – ct5845

+0

Цените свой ответ в этом случае намного лучше, чем добавление зависимости к ElementRef! – ct5845

+4

Это то, что предлагает Angular. Только компоненты поддерживают добавление таблиц стилей (встроенные или импортные). ('styles',' styleUrls'). –

4

Я прочитал ваш комментарий ниже первого ответа. Я не знаю, как вы сможете применить свои 30 правил. But few ways are here- plunker.

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

Просто введите элемент, как обычно, используя селектор атрибутов. Создайте файл 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); 
    } 
} 
+0

Использование первого подхода не сработало для меня. Использование углового 2.4. Если мне нужно импортировать в global.scss, я теряю инкапсуляцию стиля. Вы можете установить только настраиваемый класс в директиву или использовать @Component без инкапсуляции вида. – aelkz

+0

работает для меня. Изменен 'parentElement {ion-card {}}' to '[parentElement] {}', когда я изменил селектор элементов на селектор атрибутов и добавил селектор атрибутов к элементу 'ion-card' в моем компоненте , –

+0

@aelkz: Я немного опоздал на вечеринку, но он работает для меня в Angular 5 и Ionic 3. Вы проверили, что селектор в scss не такой же, как в файле .ts? aka, в файле .ts обычно говорится «selector: [mySelectorSomething]», и для того, чтобы scss имел какой-то эффект, он должен ссылаться на все строчные буквы, ака [myselectorsomething]: {}, как указано в приведенном выше примере. Это довольно тонко и не очень логично, поэтому легко пропустить (это было по крайней мере для меня). – yogibimbi

9

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

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

два вариант:

1)

Вы можете сказать, Угловой каскад ваших стилей вниз через все его потомок, используя :host /deep/ .some-style-to-cascade-down-like-normal {} или заменить /deep/ с >>>. См. Angular's Docs об этом.

три важные вещи, чтобы отметить:

  • ViewEncapsulation должен быть (эмулировать) состояние его по умолчанию
  • Угловое/хром являются протестующий оба эти синтаксисом, пока они работают на лучший подход
  • Если у вас «повторно используя угловую CLI, вы должны использовать /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 Material 2's Button использует этот же подход для решения этой проблемы.

И вот замечательная статья под названием All the Ways to Add CSS to Angular 2 Components, которая привела меня к этому осознанию и объясняет, как Angular рассматривает все три свойства ViewEncapsulation.

+2

upvote для «encapsulation: ViewEncapsulation.None»: D –

+0

«Угловой материал 2's Button использует этот же подход для решения этой проблемы». - они используют используемую вами технику, а селектор - как директивный. Но в отличие от этой темы они не пытались добавить стили в директиву. Для тех, кто решил преобразовать свою директиву в компонент только для этого преимущества стиля, какой шаблон вы используете? Не могли бы вы добавить свой. \ My-highlight.component.html, чтобы мы могли увидеть, как это сделать? И разве это не противоречит другим компонентам, сделанным из одного и того же элемента? например jcairney

0

же, как @ 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' 
    ); 
    } 
} 
Смежные вопросы