新需求一来,说添加鼠标点击组件外部关闭组件的功能,作者果断就学习了一下Directive,接下来将从我的处理过程出发完成Directive的讲解。
一.基于Directive功能的点击组件外部关闭组件功能
- 编写Directive实现:监听document的click事件,并获取event的target内容(DOM),判断是否是当前DOM的子元素(通过注入的ElementRef),从而决定是否触发事件,部分代码:
@Directive({ selector: '[clickOutside]' }) export class ClickOutsideDirective { constructor(private elementRef: ElementRef) { } @Output() public clickOutside = new EventEmitter<MouseEvent>();//发射事件给使用了该Directive的组件 @HostListener('document:click', ['$event', '$event.target']) public onClick(event: MouseEvent, targetElement: HTMLElement): void { if (!targetElement) {//判断是否点击了对应的dom,如果没点击则不触发,点击则触发 return; } //判断点击的组件是否是当前组件的子组件 const clickedInside = this.elementRef.nativeElement.contains(targetElement); if (!clickedInside) {//如果是子组件则不触发,不是则触发 this.clickOutside.emit(event); } } }
- 使用该Directive的代码(作为Dom的属性使用自定义指令)
<div (clickOutside)="closeSearchBar($event)" (click)="clickSearch($event)"></div>
- 这是会发现一个问题,当点击了此组件时也触发了click事件,因为是通过判断是否是子组件不成立则将会把组件关闭,则需要在click时的方法中添加取消默认事件与事件传播的内容
clickSearch(event) { event.preventDefault(); event.stopPropagation(); }
晚上回家再添加对应的Directive学习内容…