Angular7自定義屬性指令控制第三方組件

最近前端框架轉移到螞蟻的Ng-Alain和Ng-Zorro上,須要把咱們本身的一些前端數據邏輯對接到Ng-Zorro提供的組件上,以簡化前端代碼。之前的作法是定義一組本身的自定義組件來包裝Ng-Zorro提供的組件,但這個方法的缺點是頁面上很難直接使用Ng-Zorro組件的屬性、事件和其餘特性,除非自定義組件把Ng-Zorro組件的屬性和事件都暴露出來,Ng-Zorro組件的屬性事件很是多,所有暴露出來太麻煩,不太現實。html

忽然想到是否可以利用Angular自定義指令控制Ng-Zorro組件,這樣頁面上放置的不是自定義組件,而是Ng-Zorro組件,而後附加上一個本身寫的自定義指令,添加本身的一些屬性和事件,頁面上仍然可使用全部的Ng-Zorro組件的屬性和事件。前端

網上找到的Angular自定義屬性指令的例子大多都是注入ElementRef和Renderer2,控制html標籤的屬性。沒找到自定義指令控制第三方組件的例子。最早想到的是經過@Input方式傳入Ng-Zorro組件的實例。以下,自定義屬性指令TreeSelectDirective控制Ng-Zorro的下拉樹組件NzTreeSelectComponent前端框架

自定義指令的ts文件:框架

@Directive({
    selector: '[myTreeSelect]',
    exportAs:'myTreeSelect'
})
export class TreeSelectDirective implements OnChanges,OnDestroy,OnInit,AfterViewInit {
    @Input("myTreeSelect")
    container:NzTreeSelectComponent=null;
    
    @Input("myProp")
    prop:string='';
    
    @Output("ev")
    e:EventEmitter<any>=new EventEmitter();
    
}

頁面的HTML模板:測試

<nz-tree-select #t [myTreeSelect]='t' [myProp]='x' (ev)='onEv($event)' ...

這個方法能夠在指令類TreeSelectDirective得到組件nz-tree-select的實例,而且控制nz-tree-select組件,但由於組件實例是在@Input中傳入,而@Input是在生命週期的ngOnInit鉤子被調用時才傳入,而組件的ngOnInit鉤子比指令的ngOnInit鉤子先被調用,這意味着指令得到組件的實例以前,組件實例的各個輸入屬性已經完成初始化。這會帶來一些問題,Ng-Zorro組件的有些屬性初始化以後再設置就沒法生效(多是Zorro的bug),必須在Ng-zorro組件ngOnInit鉤子調用前設置這些屬性值才能生效,因此經過@Input傳入組件實例,沒法設置這些屬性的值並使其生效。code

另外,<nz-tree-select #t [myTreeSelect]='t' 這樣的寫法也太累贅,不優雅。後來發現,nz-tree-select之類的組件也支持Angular官方ngModel指令,因而查看ngModel指令如何和nz-tree-select組件交互,發現ngModel指令構造器中注入了ControlValueAccessor實例。htm

而後猜測,既然指令能夠注入ControlValueAccessor,是否是也能夠直接注入NzTreeSelectComponent,因而試驗:生命週期

@Directive({
    selector: '[myTreeSelect]',
    exportAs:'myTreeSelect'
})
export class TreeSelectDirective implements OnChanges,OnDestroy,OnInit,AfterViewInit {
    
    @Input("myProp")
    prop:string='';
    
    @Output("ev")
    e:EventEmitter<any>=new EventEmitter();
    
    constructor(private container:NzTreeSelectComponent){
        // console.info(nzComp);
    }
}

頁面的HTML模板:事件

<nz-tree-select myTreeSelect [myProp]='x' (ev)='onEv($event)' ...

測試發現nz-tree-select成功注入指令實例,constructor被調用的時候,nz-tree-select組件的@Input輸入屬性尚未初始化,能夠在constructor中設置nz-tree-select組件的屬性。並且代碼也更優雅簡潔。string

相關文章
相關標籤/搜索