Skip to content

Angular 2 属性指令 vs 结构指令 #11

@semlinker

Description

@semlinker

Angular 2 的指令有以下三种:

  • 组件(Component directive):用于构建UI组件,继承于 Directive 类
  • 属性指令(Attribute directive): 用于改变组件的外观或行为
  • 结构指令(Structural directive): 用于动态添加或删除DOM元素来改变DOM布局

组件

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 属性

使用常量

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

使用变量

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

具体示例:

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.] 的语法:

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

通过上面的例子,可以看出结构指令和属性指令的区别。结构指令是以 * 作为前缀,这个星号其实是一个语法糖。它是 ngIf 和 ngFor 语法的一种简写形式。Angular 引擎在解析时会自动转换成 标准语法。

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, HostListener} from "@angular/core";
    
    @Directive({
      selector: '[exeBackground]'
    })
    export class BeautifulBackgroundDirective {
      private _defaultColor = 'yellow';
      private el: HTMLElement;
    
      @Input('exeBackground')
      backgroundColor: string;
    
      constructor(el: ElementRef) {
        this.el = el.nativeElement;
        this.setStyle(this._defaultColor);
      }
    
      @HostListener('click')
      onClick() {
        this.setStyle(this.backgroundColor || this._defaultColor);
      }
    
      private setStyle(color: string) {
        this.el.style.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;
}

总结

本文主要介绍了 Angular 2 中的属性指令和结构指令,通过具体示例介绍了 Angular 2 常见内建指令的使用方式和区别。最终,我们通过自定义属性指令和自定义结构指令两个示例,展示了如何开发自定义指令。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions