簡體   English   中英

指令中的 Angular2 樣式

[英]Angular2 Styles in a Directive

在給定的 Attribute 指令示例(即添加外觀/行為的指令)中,我們在宿主元素上有一個相當簡單的樣式設置.. 例如

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 = 模擬/默認是否重要?

您可以使用主機綁定來綁定到樣式屬性:

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

或者

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

雖然其他答案在大多數情況下都有幫助,但您似乎需要更傳統的 CSS 樣式表方法,就像我有一個用例一樣。

問題是 Angular 的默認模擬 Shadow DOM,它僅在宿主元素內限定樣式。

兩個選項:

1)

您可以使用:host /deep/ .some-style-to-cascade-down-like-normal {}或將/deep/替換為>>>來告訴 Angular 將您的樣式級聯到它的所有后代。 請參閱Angular 的文檔

需要注意的三個重要事項:

  • ViewEncapsulation 需要為其默認(模擬)狀態
  • Angular/Chrome 正在棄用這兩種語法,同時他們正在研究更好的方法
  • 如果您使用的是 Angular 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 的 Button使用同樣的方法來解決這個問題。

這是一篇很棒的文章,名為“向 Angular 2 組件添加 CSS 的所有方法”,它讓我意識到了這一點,並解釋了 Angular 如何處理所有三個 ViewEncapsulation 屬性。

我已閱讀您在第一個答案下方的評論。 我不知道你將如何應用你的 30 條規則。 但是這里很少有方法 - plunker

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

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

這個答案為時已晚,但在我的同類需求中使用了一個棘手的解決方案,所以我覺得它可能對某人有所幫助。

我是按照以下方式完成的,它對我有用

<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...

}

工作示例

只需像通常使用屬性選擇器一樣設置元素樣式即可。 在與您的指令相同的文件夾中創建一個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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM