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

相关文章
相关标签/搜索