Angular8深刻了解Directive指令

angular指令,目的在於影響Dom佈局,或者修改Dom屬性。css

Directive分類

Component

an extension of @Directive()html

Demo
import { Component, OnInit } from '@angular/core';
 @Component({  selector: 'idata',  templateUrl: './user.component.html',  styleUrls: ['./user.component.scss'] }) export class UserComponent implements OnInit {   constructor() { }   ngOnInit(): void {  }  } 複製代碼
  • @Component定義在class上
  • templateUrl、template定義視圖模板
@Component源碼
export declare interface Component extends Directive {
  changeDetection?: ChangeDetectionStrategy;   viewProviders?: Provider[];   moduleId?: string;   templateUrl?: string;   template?: string;   styleUrls?: string[];   styles?: string[];   animations?: any[];   encapsulation?: ViewEncapsulation;   interpolation?: [string, string];   entryComponents?: Array<Type<any> | any[]>;   preserveWhitespaces?: boolean; } 複製代碼

從中咱們得出以下:web

  • Component是一種特殊的指令
  • Component 上述自有屬性,都是可選
  • 那麼Directive的源碼又是什麼呢?
@Directive源碼
export declare interface Directive {
  selector?: string;   inputs?: string[];   outputs?: string[];   providers?: Provider[];   exportAs?: string;   queries?: {  [key: string]: any;  };   host?: {  [key: string]: string;  };   jit?: true; } 複製代碼

屬性指令

Attribute directives are used as attributes of elementsbootstrap

內置指令
  • NgStyle
  • NgClass
自定義指令
  • step 1:
# 要求不能ng開頭
ng generate directive highlight 複製代碼
  • code以下:
# src/app/highlight.directive.ts 
import { Directive } from '@angular/core';  @Directive({  selector: '[appHighlight]' }) export class HighlightDirective {  constructor() { } } 複製代碼
  • step 2: 添加指令處理邏輯
import { Directive, ElementRef } from '@angular/core';
 @Directive({  selector: '[appHighlight]' }) export class HighlightDirective {  constructor(el: ElementRef) {  # 修改元素背景  el.nativeElement.style.backgroundColor = 'yellow';  } } 複製代碼
  • step3: 模塊中聲明指令的存在
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';  import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HighlightDirective } from './highlight.directive';  @NgModule({  declarations: [  AppComponent,  HighlightDirective # 視圖中聲明指令的引用  ],  imports: [  BrowserModule,  AppRoutingModule,  ],  providers: [],  bootstrap: [AppComponent],  exports: [] }) export class AppModule { } 複製代碼
  • step 4: 應用指令
<p appHighlight>Highlight me!</p>
複製代碼

結構指令

Structural directives are responsible for HTML layoutsegmentfault

  • 結構指令,影響當前元素以及後代元素
  • 結構指令,大多以*開頭
內置結構指令
  • ngIf
# false,不渲染元素,而非渲染後隱藏
<div *ngIf="hero" class="name">{{hero.name}}</div>  複製代碼
  • ngIf false爲什麼不隱藏元素,而是刪除元素? 這裏應該是框架設計者針對利弊的取捨吧!若是元素僅僅隱藏,那麼元素還佔據原來的位置,那麼對應的鼠標事件,有可能仍是存在的,那麼就會影響現有組件的功能,視圖渲染數據。 具體的能夠參考這邊文章 針對visible,opacity,hiden之間區別,寫的挺好的!
  • angular 編譯ngIf爲如下代碼:
    <ng-template [ngIf]="hero">
    <div class="name">{{hero.name}}</div> </ng-template> 複製代碼
  • ngFor
<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">
 ({{i}}) {{hero.name}} </div> 複製代碼
  • angular編譯爲如下代碼 :
<ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById">
 <div [class.odd]="odd">({{i}}) {{hero.name}}</div> </ng-template> 複製代碼
  • ngSwitch
<div [ngSwitch]="hero?.emotion">
 <app-happy-hero *ngSwitchCase="'happy'" [hero]="hero"></app-happy-hero>  <app-sad-hero *ngSwitchCase="'sad'" [hero]="hero"></app-sad-hero>  <app-confused-hero *ngSwitchCase="'confused'" [hero]="hero"></app-confused-hero>  <app-unknown-hero *ngSwitchDefault [hero]="hero"></app-unknown-hero> </div> 複製代碼
自定義結構指令
  • step 1:
    ng generate directive appUnless
    複製代碼
    • code 以下:
    import { Directive } from '@angular/core';
      @Directive({  selector: '[appUnless]'  })  export class AppUnlessDirective {   constructor() { }   } 複製代碼
  • step 2: 定義元素邏輯
import { Directive, TemplateRef, ViewContainerRef, Input } from '@angular/core';
 @Directive({  selector: '[appUnless]' }) export class AppUnlessDirective {   private hasView = false;   constructor(  private templateRef: TemplateRef<any>,  private viewContainer: ViewContainerRef) { }   @Input() set appUnless(condition: boolean) {  if (!condition && !this.hasView) {  this.viewContainer.createEmbeddedView(this.templateRef);  this.hasView = true;  } else if (condition && this.hasView) {  this.viewContainer.clear();  this.hasView = false;  }  }  }  複製代碼
  • step 3: 聲明指令
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';  import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HighlightDirective } from './highlight.directive'; import { AppUnlessDirective } from './app-unless.directive';  @NgModule({  declarations: [  AppComponent,  HighlightDirective,  AppUnlessDirective # 聲明結構指令  ],  imports: [  BrowserModule,  AppRoutingModule,  ],  providers: [],  bootstrap: [AppComponent],  exports: [] }) export class AppModule { }  複製代碼
  • step 4: 應用指令
<p *appUnless="condition" class="unless a">
 (A) This paragraph is displayed because the condition is false. </p>  #ts public condition = false; constructor(private domSanitizer: DomSanitizer){  interval(2000).subscribe(() => {  this.condition = !this.condition;  }); } 複製代碼

更多推薦

Rxjs 操做符分類後的那些事

Angular Render2你瞭解嗎?

Angular8 平常開發填坑指南

參考

Angular

相關文章
相關標籤/搜索