指令中的Angular2样式

时间:2016-03-10 11:38:41

标签: angular angular2-directives

在给定的属性指令示例中(即添加外观/行为的指令),我们在主机元素上设置了一个相当简单的样式...例如

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

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

我可以使用样式而不是设置样式吗? e.g。

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

这对我来说似乎不起作用?

我做了一些稍微复杂的事情,这导致了相当数量的单一代码,设置了很多风格,使用了AnimationBuilder等等。对我而言,感觉就像把它分成几类更好CSS中的动画。

ViewEncapsulation =模拟/默认是否重要?

6 个答案:

答案 0 :(得分:34)

您可以使用主机绑定绑定到样式属性:

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

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

答案 1 :(得分:18)

虽然其他答案在大多数情况下都很有用,但您似乎需要一种更传统的CSS样式表方法,就像我有一个用例一样。

问题是Angular默认模拟一个Shadow DOM,它只在hosts元素中定义样式。

两个选项:

<强> 1)

您可以告诉Angular使用:host /deep/ .some-style-to-cascade-down-like-normal {}将您的样式级联到其所有后代,或者将/deep/替换为>>>。有关此内容,请参阅Angular's Docs

需要注意的三个重要事项:

  • ViewEncapsulation需要是其默认(模拟)状态
  • Angular / Chrome在使用更好的方法时,正在弃用这两种语法
  • 如果您正在使用Angular CLI,则必须使用/deep/代替>>>

<强> 2)

虽然你会松开范围内的组件封装(如果在你的情况下这很重要),这里有一个使用&#34; myHighlight&#34; 作为指令虽然 TypeScripted as a component 所以我可以导入样式表:

USAGE:
<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 :(得分:4)

我在第一个回答下面看过你的评论。我不知道你怎么能应用你的30条规则。 But few ways are here- plunker

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

答案 3 :(得分:2)

与@ 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'
    );
  }
}

答案 4 :(得分:1)

  

这个答案为时已晚,但在我的同类要求中使用了一个棘手的解决方案,因此我认为它可能会对某人有所帮助。

     

我是通过以下方式完成的,并且对我有用

import threading

def print_hello_world():
    threading.Timer(1, print_hello_world).start()
    print('Hello World')

print_hello_world()

Working Example

答案 5 :(得分:0)

只需使用属性选择器正常设置元素样式即可。在与指令相同的文件夹中创建myHighlight.directive.scss(或其他)文件,并在其中编写样式:

[myhighlight] {
  background-color: yellow;
}

如果您的应用没有自动包含样式文件,只需将其导入主样式文件即可。对于Ionic 2中的我来说它是自动拾取的。

如果要使用特定的类而不是属性选择器,请使用“渲染器”添加类。

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