极客angular知识分享(8)-- 属性指令

属性指令


 

定义

能够改变宿主元素行为和外观的类

 

创建简单的属性指令

  1. 使用ng生成指令

    ng g d directive/mydirctive // directive目录下生成指令mydirctive

  2. 指令文件

    import { Directive } from '@angular/core';
     import { ElementRef } from '@angular/core';
    
     @Directive({
     selector: '[storeMydirctive]'
     })
     export class MydirctiveDirective {
    
     constructor(element:ElementRef) {
         // 将宿主元素的背景类追加bg-info
         element.nativeElement.classList.add('bg-info');
     }
    
     }
  3. 使用指令

    商品名称 商品描述
    {{item.id}} {{item.name}} {{item.description}}
  4. 声明指令

    使用指令前需要在模块中声明指令

    import { NgModule } from '@angular/core';
     import { SimAttrDirectiveComponent } from '../sim-attr-directive/sim-attr-directive.component';
     import { BrowserModule } from '../../../node_modules/@angular/platform-browser';
     import { MydirctiveDirective } from '../directive/mydirctive.directive';
     import { AppModule } from '../app.module';
    
     @NgModule({
     imports: [
         BrowserModule, // 包含了ngFor等内置指令
     ],
     // 声明一个指令
     declarations: [SimAttrDirectiveComponent, MydirctiveDirective]
     })
     export class AttrmoduleModule { }

 

指令访问应用程序数据

  1. 为指令构造方法添加注解Attibute参数获取数据

    import { Directive, Attribute } from '@angular/core';
     import { ElementRef } from '@angular/core';
    
     @Directive({
     selector: '[storeMydirctive]'
     })
     export class MydirctiveDirective {
    
     constructor(element:ElementRef, @Attribute('store-mydirective-class') bgClass:string) {
         // 将宿主元素的背景类追加bg-info
         element.nativeElement.classList.add(bgClass || 'bg-info');
     }
    
     }
    // 使用属性参数
    
    商品名称 商品描述
    {{item.id}} {{item.name}} {{item.description}}

    不支持表达式,元素属性值只支持静态

  2. 使用输入参数

    import { Directive, ElementRef, Input } from '@angular/core';
    
         @Directive({
         selector: '[storeInputdirective]'
         })
         export class InputdirectiveDirective {
    
         @Input('in-attr')
         storeinputattr:string;
    
         constructor(private element:ElementRef) {
         }
    
         ngOnInit(){
             this.element.nativeElement.classList.add(this.storeinputattr || 'bg-info')
         }
     }
    商品名称 商品描述
    {{item.id}} {{item.name}} {{item.description}}

    输入属性一定要加[],angular才识别,且后面跟的是表达式。
    输入属性是在ngOnInit方法中获取,而不是构造方法。

 

指令生命周期钩子

  1. ngOnInit: 在angular设置了所有输入属性之后,调用此方法
  2. ngOnChanges: 当输入属性的值发送改变时调用此方法,此方法调用发送在ngOnInit之前
  3. ngDoCheck: 当angular运行变更检测时,调用此方法,以便指令有机会更改与输入属性不直接关联的任何状态
  4. ngAfterContentInit: 在指令的内容经过初始化之后,将调用此方法
  5. ngAfterContentChecked: 在对指令的内容进行检查(变更检测过程的一部分)后调用该方法
  6. ngOnDestroy:在angular销毁指令之前立即调用

 

指令响应输入属性变化

  1. ngOnChanges 在ngOnInit之前调用一次,之后每当指令的任何属性更改时就调用一次
  2. 其参数为SimpleChange,属性如下:

    previousValue 属性的前值
    currentValue 属性的当前值
    isFirstChange() 如果ngOnChanges发送在ngOnInit之前,返回true(可以找到实际并未应用的值)

    import { Directive, ElementRef, Input, SimpleChange } from '@angular/core';
    
        @Directive({
        selector: '[storeInputdirective]'
        })
        export class InputdirectiveDirective {
    
        @Input('in-attr')
        storeinputattr:string;
    
        constructor(private element:ElementRef) {
        }
    
        ngOnInit(){
            this.element.nativeElement.classList.add(this.storeinputattr || 'bg-info')
        }
        ngOnChanges(changes:{[property:string]:SimpleChange}){
            let classList = this.element.nativeElement.classList;
            let change = changes['storeinputattr'];
            if(!change.isFirstChange() && classList.contains(change.previousValue)){
            classList.remove(change.previousValue);
            }
            if(!classList.contains(change.currentValue)){
            classList.add(change.currentValue)
            }
        }
    }
    属性指令--输入参数
    // 此处根据select的值变化更改背景色
    商品名称 商品描述
    {{item.id}} {{item.name}} {{item.description}}

 

自定义事件

  1. 使用Output定义事件
  2. 绑定指令事件并调用Output变量的emit方法
  3. 宿主元素定义方法响应Output定义的事件
    import { Directive, ElementRef, Input, SimpleChange, Output, EventEmitter } from '@angular/core';
    
     @Directive({
     selector: '[storeInputdirective]'
     })
     export class InputdirectiveDirective {
    
         @Input('in-attr')
         storeinputattr:string;
    
         @Input('itempro')
         product:any;
         // 定义了事件传送的数据类型为string
         @Output('directEvent')
         click = new EventEmitter()
    
         constructor(private element:ElementRef) {
             this.element.nativeElement.addEventListener("click", e=>{
             if(this.product){
                 this.click.emit(this.product.name)
             }
             })
         }
    
         ngOnInit(){
             this.element.nativeElement.classList.add(this.storeinputattr || 'bg-info')
         }
         ngOnChanges(changes:{[property:string]:SimpleChange}){
             let classList = this.element.nativeElement.classList;
             let change = changes['storeinputattr'];
             if(!change){
             return;
             }
             if(!change.isFirstChange() && classList.contains(change.previousValue)){
             classList.remove(change.previousValue);
             }
             if(!classList.contains(change.currentValue)){
             classList.add(change.currentValue)
             }
         }
     }
     
    商品名称 商品描述
    {{item.id}} {{item.name}} {{item.description}}

 

绑定宿主元素

  1. @HostListener('click') 绑定宿主元素的事件(此处是click事件)
  2. @HostBinding('class') 绑定宿主元素的属性(此处是class属性)
  3. 可以更加优美的方式实现自定义事件

 

import { Directive, Output, Input, EventEmitter, HostListener, HostBinding } from '@angular/core';

@Directive({
  selector: '[storeHostbinddirective]'
})
export class HostbinddirectiveDirective {
  @Input('in-attr')
  @HostBinding('class')
  storeinputattr:string;

  @Input('itempro')
  product:any;
// 定义了事件传送的数据类型为string
  @Output('directEvent')
  click = new EventEmitter()

  @HostListener('click')
  trigger(){
    if(this.product != null){
      this.click.emit(this.product.name)
    }
  }

}

 

属性指令--绑定宿主元素属性和事件
商品名称 商品描述
{{item.id}} {{item.name}} {{item.description}}

 

导出指令为模板变量

  1. exportAs 指令导出为一个变量
  2. 宿主元素使用模板变量引用导出的变量
    import { Directive, HostBinding, Input, SimpleChange, Output, EventEmitter, HostListener } from '@angular/core';
    
     @Directive({
     selector: '[storeExportdirective]',
     exportAs: 'exportDirective'
     })
     export class ExportdirectiveDirective {
         direciton:string='None';
    
         @Input()
         cModel:string='';
    
         @HostBinding('value')
         hostmodel:string='';
    
         ngOnChanges(changes:{[property:string]:SimpleChange}){
         let change = changes["cModel"];
    
         if(change.currentValue && change.currentValue != this.hostmodel){
             this.hostmodel = change.currentValue || '';
             this.direciton = "Model";
         }
         }
    
         @Output('cModelChange')
         update = new EventEmitter();
         @HostListener('input', ['$event.target.value'])
         updateValue(newVal : string){
         console.log(newVal)
         this.direciton = 'Element'
         }
    
    
     }
    属性指令--导出指令用于模板变量
    Direction: {{exDirective.direciton}}
    商品名称 商品描述
    {{item.id}} {{item.name}} {{item.description}}

你可能感兴趣的:(angular学习)