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

相关文章
相关标签/搜索