Angular 指令单击角度6的外侧

Angular 指令单击角度6的外侧,angular,angular2-directives,angular6,Angular,Angular2 Directives,Angular6,我将我的Angular从4升级到6,结果我的点击关闭策略出现问题,所有组件都停止工作 我的指示: import{Directive,Output,EventEmitter,ElementRef,HostListener}来自“@angular/core”; @指示({ 选择器:“[单击外部]” }) 导出类ClickOutside指令{ 构造函数(私有_elementRef:elementRef){} @输出() public clickOutside=new EventEmitter(); @

我将我的Angular从4升级到6,结果我的点击关闭策略出现问题,所有组件都停止工作

我的指示:

import{Directive,Output,EventEmitter,ElementRef,HostListener}来自“@angular/core”;
@指示({
选择器:“[单击外部]”
})
导出类ClickOutside指令{
构造函数(私有_elementRef:elementRef){}
@输出()
public clickOutside=new EventEmitter();
@HostListener('文档:单击',['$event.target']))
公共onClick(targetElement){
const clickedInside=此。_elementRef.nativeElement.contains(targetElement);
如果(!clickedInside){
this.clickout.emit(空);
}
}
}
使用此指令的My component.html:


{{navTitle}}

您在模板中引用了“this”,这是不必要的。我为该指令做了一个工作示例:

没有理由对div发出两次指令

<div id="sidenav" *ngIf="opened" class="sidenav" [ngClass]="getClasses()" [ngStyle]="getStyles()" (clickOutside)="closeOutsideSidenav()">
    <header> {{ navTitle }} </header>
    <i *ngIf="showCloseButton" class="iconic iconic-x-thin close-icon" (click)="closeSidenav()"></i>
    <ng-content></ng-content>
</div>

<div *ngIf="backdrop && opened" class="sidenav-backdrop"></div>

{{navTitle}}

运行内部
NgZone

例如:

export class AppComponent {
  opened: boolean = false;

  constructor(private ngZone: NgZone) {
  }

  closeOutsideSidenav(e) {
    this.ngZone.run(() => {
      this.opened = !this.opened;
    })
  }
}
我把代码添加到stackblitz。(点击“突出显示我!”)查看:


组件:

导出类SomeClass{
@ViewChild(“insideElement”)insideElement;
@HostListener('文档:单击',['$event.target']))
公共onClick(targetElement){
const clickedInside=this.insideElement.nativeElement.contains(targetElement);
如果(!clickedInside){
log('outside clicked');
}
}
}

这是对上面@YoungHyeong-Ryu-answer的修改,但带有取消订阅功能,以便在卸载组件时处理程序停止工作

演示

从'@angular/core'导入{Component,Input,OnInit,OnDestroy,ViewChild};
@组成部分({
选择器:“应用程序单击外部”,
模板:`在我外面单击`
})
导出类ClickOutside组件实现OnInit、OnDestroy{
@ViewChild('insideElement',{static:false})insideElement;
公共ngOnInit(){
this.onDocumentClick=this.onDocumentClick.bind(this);
document.addEventListener('click',this.onDocumentClick);
}
公共恩格德斯特罗(){
document.removeEventListener('click',this.onDocumentClick);
}
受保护的onDocumentClick(事件:MouseeEvent){
if(this.insideElement.nativeElement.contains(event.target)){
返回;
}
log('Clicked out!');
}
}
在这里,我们删除destroy上的事件侦听器。
此外,通常由addEventListener添加的方法在全局上下文中执行(而不是
上下文);因此,我们应该注意它,并将
onDocumentClick
方法绑定到
this
(我们在
ngOnInit
中执行)。现在我们可以在
onDocumentClick中使用
this
如果只使用一次指令,是否有帮助?删除
单击外部
并仅使用
(单击外部)=…
)?我尝试了不起作用谢谢提示,但它不起作用。如果不是提示,则不调用“closeOutsideSidenav()”方法。这是一个有效的例子。看看stackblitz,看看你的例子和我的有什么不同。你的stackblitz代码对我不起作用:(@Everett@RitwickDey怎么会呢?我试着运行到
NgZone
,然后它就开始工作了。(我指的是你的代码)“通过run运行函数允许您从在角度区域外执行的任务(通常通过runOutsideAngular启动)重新进入角度区域。"此问题与Angular zone无关。不幸的是,此问题不支持取消订阅,即使组件已损坏也不支持继续工作。因此,我建议在ngOnInit中手动注册事件,并在中取消订阅ngOnDestroy@MaximGeorgievskiy你是怎么做到的?我不明白语法是什么好的。听起来很不一样。你能自己回答吗?@tatsu好主意。我添加了一个单独的答案,带有一个工作演示的链接。等等,angular是否会自动破坏HostListener的订阅?和
文档。
是旧语法,我很确定我们可以避免在较新的angular语法中调用文档十,。