打开第二个时关闭下拉菜单/document.click 被点击阻止 Angular 5

Close dropdown when second is opened / document.click blocked by click Angular 5

我正在尝试为下拉菜单创建一个指令,只要我使用的是单个指令,它就很有魅力。我可以使用以下代码在下拉菜单外点击:

@HostListener('document:click', ['$event'])
  onDocumentClick(event: any): void {
    console.log("document click");
    // close
}
@HostListener('click')
  onClick(): void {
    console.log('click on ');  
    // toggle  
  }

当创建了 2 个下拉菜单时会出现问题。我想在第二个打开时关闭第一个下拉菜单,但是当我点击第二个下拉菜单时,只有 "click" 事件被触发并且 "document.click" 没有被执行。我希望这两个事件都应该发生,除非我在点击时明确使用 preventDefault 但显然这是自动发生的。

Angular5 中打开第二个下拉菜单时关闭第一个下拉菜单的正确方法是什么?

也许你可以尝试这样的事情:

 @HostListener('document:click', ['$event'])
  onClick(event) {
    if(this.eRef.nativeElement.contains(event.target)) {
      // toggle logic
    } else {
      // close logic
    }
}

因此,不是让两个事件相互冲突,而是让一个事件具有两条逻辑来准确处理您需要的内容,具体取决于您是在元素本身内部还是外部单击。说得通?

这取自

创建一个可以随处使用的指令怎么样?

@Directive( {
    selector : '[clicked-outside]' ,
    host     : {
        '(document:click)' : 'onClick($event)',
        '(document:touch)' : 'onClick($event)',
        '(document:touchstart)' : 'onClick($event)'
    } 
} )
export class ClickedOutsideDirective {
    @Input( 'clicked-outside' ) callback : Function;

    constructor ( private _el : ElementRef ) {
    }

    private onClick ( event : any ) {
        if ( this.clickedOutside( event ) ) {
            if ( this.callback ) {
                this.callback();
            }
        }
    }

    private clickedOutside ( event : any ) {
        let clickedTarget = event.target;
        let host          = this._el.nativeElement;
        do {
            if ( clickedTarget === host ) {
                return false;
            }
            clickedTarget = clickedTarget.parentNode;
        } while ( clickedTarget );
        return true;
    }
}

你可以像这样使用它:

@Component({
   selector:'your-dropdown',
   template:`
       <div class="your-dropdown-top-most-wrapper" [clicked-outside]="onClickOutSide"></div>

   `
})
export class YouDropdownComponent{


   public onClickOutSide = ()=>{


        this.closeMyDropdown()// this is your function that closes the dropdown
   }
}