Angular 2 Directive

Angular 2 的指令分爲如下三種:html

  • 組件(Component directive):用於構建UI組件,繼承於 Directive 類typescript

  • 屬性指令(Attribute directive): 用於改變組件的外觀或行爲segmentfault

  • 結構指令(Structural directive): 用於動態添加或刪除DOM元素來改變DOM佈局app

圖片描述

Angular 2 組件

圖片描述

組件示例:less

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

@Component({
  selector: 'my-app', // 定義組件在HTML代碼中匹配的標籤
  template: `<h1>Hello {{name}}</h1>`, // 指定組件關聯的內聯模板
})
export class AppComponent  {
  name = 'Angular'; 
}

Angular 2 內置屬性指令

1.ngStyle指令: 用於設定給定 DOM 元素的 style 屬性佈局

綁定常量this

<div [ngStyle]="{'background-color': 'green'}"></div>

綁定表達式spa

<div [ngStyle]="{'background-color': person.country === 'UK' ? 'green' : 'red'}">

具體示例:code

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

@Component({
    selector: 'ngstyle-example',
    template: `<h4>NgStyle</h4>
    <ul *ngFor="let person of people">
        <li [ngStyle]="{'color': getColor(person.country)}">
            {{ person.name }} ({{person.country}})
        </li>
    </ul>
    `
})
export class NgStyleExampleComponent {

    getColor(country: string) {
        switch (country) {
            case 'CN':
                return 'red';
            case 'USA':
                return 'blue';
            case 'UK':
                return 'green';
        }
    }

    people: any[] = [
        {
            name: "Semlinker",
            country: 'CN'
        },
        {
            name: "Donald John Trump",
            country: 'USA'
        },
        {
            name: "Daniel Manson",
            country: 'UK'
        }
    ];
}

上面的例子,除了使用 ngStyle 指令,咱們還能夠使用 [style.<property>] 的語法:htm

<ul *ngFor="let person of people">
     <li [style.color]="getColor(person.country)">
        {{ person.name }} ({{person.country}})
     </li>
</ul>

2.ngClass指令:用於動態的設定 DOM 元素的 CSS class

綁定常量

<div [ngClass]="{'text-success': true }"></div>

綁定表達式

<div [ngClass]="{'text-success': person.country === 'CN'}"></div>

具體示例:

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

@Component({
    selector: 'ngclass-example',
    template: `
    <style>
      .text-success {
         color: green 
      }
      .text-primary {
          color: red
      }
      .text-secondary {
          color: blue
      } 
    </style>
    <h4>NgClass</h4>
    <ul *ngFor="let person of people">
        <li [ngClass]="{
           'text-success': person.country === 'UK',
           'text-primary': person.country === 'CN',
           'text-secondary': person.country === 'USA'  
          }"> {{ person.name }} ({{person.country}})
        </li>
    </ul>
    `,
   
})
export class NgClassExampleComponent {

    people: any[] = [
        {
            name: "Semlinker",
            country: 'CN'
        },
        {
            name: "Donald John Trump",
            country: 'USA'
        },
        {
            name: "Daniel Manson",
            country: 'UK'
        }
    ];
}

Angular 2 內置結構指令

1.ngIf指令:根據表達式的值,顯示或移除元素

<div *ngIf="person.country === 'CN'">{{ person.name }} ({{person.country}})</div>

2.ngFor指令:使用可迭代的每一個項做爲模板的上下文來重複模板,相似於 Ng 1.x 中的 ng-repeat 指令

<div *ngFor="let person of people">{{person.name}}</div>

3.ngSwitch指令:它包括兩個指令,一個屬性指令和一個結構指令。它相似於 JavaScript 中的 switch 語句

<ul [ngSwitch]='person.country'>
  <li *ngSwitchCase="'UK'" class='text-success'>
      {{ person.name }} ({{person.country}})
  </li>
   <li *ngSwitchCase="'USA'" class='text-secondary'>
      {{ person.name }} ({{person.country}})
  </li>
  <li *ngSwitchDefault class='text-primary'>
    {{ person.name }} ({{person.country}})
  </li>
</ul>

經過上面的例子,能夠看出結構指令和屬性指令的區別。結構指令是以 * 做爲前綴,這個星號實際上是一個語法糖。它是 ngIfngFor 語法的一種簡寫形式。Angular 引擎在解析時會自動轉換成 <template> 標準語法。

Angular 2 內置結構指令標準形式

1.ngIf指令:

<template [ngIf]='condition'>
   <p>I am the content to show</p>
</template>

2.ngFor指令:

<template ngFor [ngForOf]="people" let-person>
   <div> {{ person.name }} ({{person.country}}) </div>
</template>

3.ngSwitch指令:

<ul [ngSwitch]='person.country'>
  <template [ngSwitchCase]="'UK'">
      <li class='text-success'>
          {{ person.name }} ({{person.country}})
        </li>
  </template>
  <template [ngSwitchCase]="'USA'">
      <li class='text-secondary'>
          {{ person.name }} ({{person.country}})
        </li>
  </template>
  <template [ngSwitchDefault]>
      <li class='text-primary'>
          {{ person.name }} ({{person.country}})
        </li>
  </template>
</ul>

Angular 2 內置結構指令定義

1.ngIf指令定義:

@Directive({selector: '[ngIf]'})
export class NgIf {}

2.ngFor指令定義:

@Directive({selector: '[ngFor][ngForOf]'})
export class NgForOf<T> implements DoCheck, OnChanges {}

3.ngSwitch指令定義:

@Directive({selector: '[ngSwitch]'})
export class NgSwitch {}

@Directive({selector: '[ngSwitchCase]'})
export class NgSwitchCase implements DoCheck {}

@Directive({selector: '[ngSwitchDefault]'})
export class NgSwitchDefault {}

自定義屬性指令

指令功能描述:該指令用於在用戶點擊宿主元素時,根據輸入的背景顏色,更新宿主元素的背景顏色。宿主元素的默認顏色是黃色。

1.指令實現

import {Directive, Input, ElementRef, Renderer, HostListener} from "@angular/core";

@Directive({
  selector: '[exeBackground]'
})
export class ExeBackgroundDirective {
  private _defaultColor = 'yellow';

  @Input('exeBackground')
  backgroundColor: string; // 輸入屬性,用於設置元素的背景顏色

  constructor(private elementRef: ElementRef, private renderer: Renderer) {
    this.setStyle(this._defaultColor);
  }

  @HostListener('click')
  onClick() { // 監聽宿主元素的點擊事件,設置元素背景色
    this.setStyle(this.backgroundColor || this._defaultColor);
  }

  private setStyle(color: string) { // 調用renderer對象提供的API設置元素的背景顏色
    this.renderer.setElementStyle(this.elementRef.nativeElement, 
      'backgroundColor', color);
  }
}

2.指令應用:

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

@Component({
  selector: 'my-app', 
  template: `<h1 [exeBackground]="'red'">Hello {{name}}</h1>`,
})
export class AppComponent  {
  name = 'Angular'; 
}

自定義結構指令

指令功能描述:該指令實現 ngIf 指令相反的效果,當指令的輸入條件爲 Falsy 值時,顯示DOM元素。

1.指令實現

@Directive({
  selector: '[exeUnless]'
})
export class UnlessDirective {
  
  @Input('exeUnless')
  set condition(newCondition: boolean) {
    if (!newCondition) { // 建立模板對應的內嵌視圖
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      this.viewContainer.clear();
    }
  }

  constructor(private templateRef: TemplateRef<any>,
     private viewContainer: ViewContainerRef) {
  }
}

2.指令應用

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

@Component({
  selector: 'my-app',
  template: `<h1 [exeBackground]="'red'" *exeUnless="condition">Hello {{name}}</h1>`, 
})
export class AppComponent  {
  name = 'Angular'; 
  condition: boolean = false;
}

我有話說

1.自定義屬性指令中的 ElementRefRenderer 的做用

爲了可以支持跨平臺,Angular 2 經過抽象層封裝了不一樣平臺的差別,統一了 API 接口。如定義了抽象類 Renderer 、抽象類 RootRenderer 等。此外還定義瞭如下引用類型:ElementRef、TemplateRef、ViewRef 、ComponentRef 和 ViewContainerRef 等。

詳細內容請參考 - Angular 2 ElementRef

2.自定義結構指令中的 TemplateRefViewContainerRef 的做用

TemplateRef:用於表示內嵌的 template 模板元素,經過 TemplateRef 實例,咱們能夠方便建立內嵌視圖(Embedded Views),且能夠輕鬆地訪問到經過 ElementRef 封裝後的 nativeElement。須要注意的是組件視圖中的 template 模板元素,通過渲染後會被替換成 comment 元素。

ViewContainerRef:用於表示一個視圖容器,可添加一個或多個視圖。通ViewContainerRef 實例,咱們能夠基於 TemplateRef 實例建立內嵌視圖,並能指定內嵌視圖的插入位置,也能夠方便對視圖容器中已有的視圖進行管理。簡而言之,ViewContainerRef 的主要做用是建立和管理內嵌視圖或組件視圖。

詳細內容請參考 - Angular 2 TemplateRef & ViewContainerRef

3.Angular 2 中指令與組件的關係

組件繼承於指令,並擴展了與 UI 視圖相關的屬性,如 template、styles、animations、encapsulation 等。

詳細內容請參考 - Angular 2 Directive Lifecycle

圖片描述

總結

本文主要介紹了 Angular 2 中的指令,經過具體示例介紹了 Angular 2 常見內建指令的使用方式和區別。最終,咱們經過自定義屬性指令和自定義結構指令兩個示例,展現瞭如何開發自定義指令。

相關文章
相關標籤/搜索