繁体   English   中英

Angular 5-当用户在目标元素之外单击时如何触发事件

[英]Angular 5 - How to trigger event when user clicks outside targeted elements

我需要能够在用户单击外部目标元素时进行注册。 为此,我创建了一个自定义属性指令,如下所示。


ClickOutsideTargets指令

import { Directive, ElementRef, Input, Output, EventEmitter, HostListener } from '@angular/core';

@Directive({
  selector: '[clickOutsideTargets]',
})
export class ClickOutsideTargetsDirective {

    @Input()
    public targets : HTMLElement[] = [];


    @Output() 
    clickOutsideTargets = new EventEmitter();

    constructor(){

    }


    @HostListener('document:click', ['$event.target'])
    public onClick(targetElement){

     if(!targetElement){
        return;
    }

    for(var i = 0, len = this.targets.length; i < len; i++){
        if(this.targets[i].contains(targetElement)){
            return;
        }
    }

    this.clickOutsideTargets.emit(null);

  }

}

“目标”数组指定用户可以在不触发事件的情况下单击的元素。 每当用户在这些元素之外单击时,都会发出一个事件。


我希望能够使用干净且方便的以下语法将目标数组传递给指令作为输入。 每个目标均作为模板变量(#variable)给出。

<button #buttonRef class="btn btn-primary" (click) = "activate()" (clickOutsideTargets) = "deactivate()" [targets] = "[buttonRef, containerRef]"> </button>



这种方法的问题

但是,这在以下情况下不起作用:

  • 目标元素之一存在于子组件的模板中。 除非有一种方法可以从父组件的模板访问子模板的变量。

  • 目标元素之一是动态创建的,例如通过NgFor。


有办法解决这些问题吗? 或者理想情况下,有没有我没有考虑的更好的解决方案/策略。


(获得该功能的一个非常混乱的解决方案是创建一个新的模板变量来表示指令(使用指令的装饰器中的exportAs),使用ViewChild访问父组件中的指令,使用ViewChild / ViewChildren访问目标元素并手动设置指令的目标数组指向必要的元素。)这打破了精益组件的原理。

您可能想尝试一下

在您的组件中

@ViewChild('myTarget') myTarget;

@HostListener('document:click', ['$event.target'])
    onClick(targetElement) {
        const clickedInside = this.myTarget.nativeElement.contains(targetElement);
        if (!clickedInside) {
            //the click was made outside of this element
        }
    }

在你的HTML

<div #myTarget>
</div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM