【问题标题】:Close dropdown when second is opened / document.click blocked by click Angular 5打开第二个时关闭下拉菜单/ document.click 被单击 Angular 5 阻止
【发布时间】:2018-05-21 09:10:37
【问题描述】:

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

@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 但显然这会自动发生。

在打开第二个下拉菜单时,Angular 5 中关闭第一个下拉菜单的正确方法应该是什么?

【问题讨论】:

  • 我尝试使用指令来实现这一点,但没有成功。每次打开或关闭下拉列表时,我都必须向组件添加一个私有属性并标记,以便在单击另一个下拉列表时考虑关闭它。我遵循了来自@J. Frankenstein 的示例代码

标签: angular domdocument angular2-directives angular-directive


【解决方案1】:

也许你可以试试这样的:

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

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

这取自here

【讨论】:

  • 谢谢,但“内部点击”不会被触发”-> if( this._element.nativeElement.contains(event.target)) { console.log('click on '); } 不会不工作
  • 您是否有错误或根本没有进入 if?
  • 我的错,当我点击下拉菜单时,这根本不会被触发。我把控制台日志放在它之前,当我点击下拉菜单时它没有被触发。
【解决方案2】:

创建一个可以在任何地方使用的指令怎么样?

@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
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    相关资源
    最近更新 更多