Angular 5自定义指令为包装为*ngIf=false的元素激发

Angular 5自定义指令为包装为*ngIf=false的元素激发,angular,angular5,angular2-directives,angular-directive,Angular,Angular5,Angular2 Directives,Angular Directive,我正在编写一个指令,该指令应该在单击“外部”后关闭下拉列表。具有指令的元素也具有*ngIf,并且在单击时不在页面上,但指令仍在触发事件-因此,当单击=showList=true触发后showList立即变为false时,不会打开下拉列表。我如何避免这种情况 从“@angular/core”导入{指令、HostListener、ElementRef、EventEmitter、Inject、平台ID、输出、输入、OnInit、Renderer2、AfterContentInit}; 从“@angu

我正在编写一个指令,该指令应该在单击“外部”后关闭下拉列表。具有指令的元素也具有*ngIf,并且在单击时不在页面上,但指令仍在触发事件-因此,当单击=showList=true触发后showList立即变为false时,不会打开下拉列表。我如何避免这种情况

从“@angular/core”导入{指令、HostListener、ElementRef、EventEmitter、Inject、平台ID、输出、输入、OnInit、Renderer2、AfterContentInit}; 从“@angular/common”导入{isPlatformBrowser}; @指示{ 选择器:“[单击外部]” } 导出类ClickOutside指令在ContentInit之后实现{ ngAfterContentInit:void{ this.contentInitialized=true; } @InputclickOutside配置:any={}; @输出clickOutside:EventEmitter=新的EventEmitter; 私有isBrowser:boolean=false; 私有isIE11:boolean=false; 私有contentInitialized:boolean=false; constructorprivate渲染器:Renderer2,private _el:ElementRef,@InjectPLATFORM_ID private platformId:any{ this.isBrowser=isPlatformBrowserplatformId; this.isIE11=this.isBrowser&&!!窗口为any.MSInputMethodContext&&!!文档为any.documentMode; } @HostListener'文档:单击',['$event'] 公共活动{ console.logCLICKED; 如果this.contentInitialized&!this._el.nativeElement.containsevent.target | | | event.target==window.document.querySelectorthis.config.excludeLocator{ this.clickout.emitevent; } } @HostListener'document:keyup',['$event'] 私有onKeyupevent{ 如果event.keyCode==27{ this.clickout.emitevent; } } } 项目1 项目2 项目3 项目4
为了避免父事件运行,您需要从子元素停止它,您可以通过

$event.stopPropagation();
event.stopperPagation方法停止向目标发送事件的冒泡 父元素,防止任何父事件处理程序 执行


如果您想学习一些基础知识并推进更多HTML事件,您可以查看

你的HTML在任何地方都不使用clickOutside。在StackBlitz中发布一个完整的最小示例,再现问题。您是否尝试了$event.stopPropagation@JBNizet是的,没看到,这里是stackblitz@nasiruddinsaied你想打开它。菜单触发器?似乎正在工作是的,它应该停止事件。从角度来看,你知道它为什么在*ngIf=flase时被解雇吗?我认为,如果元素不在dom中,它就不应该接受任何交互,因为此时它实际上在dom中。1.页面加载-不在DOM 2中。单击触发器将在DOM 3中设置showList=true->。事件冒泡4。触发主机侦听器5。showList=false->不再在DOM中