Angular 单击对话框外部区域时关闭/隐藏对话框

Angular 单击对话框外部区域时关闭/隐藏对话框,angular,Angular,我有一个Angular应用程序,它有一个弹出对话框,用户可以在其中输入一些信息。我希望在单击应用程序中的任何区域(弹出对话框除外)时关闭或隐藏此对话框。这样,用户可以根据需要输入数据,只有在弹出对话框外部单击时,才会关闭该对话框 我可以使用(mousleave)事件,但我只希望在用户单击主应用程序中的某个位置时隐藏弹出对话框(而不是弹出对话框)。在下图中,这意味着蓝色区域的任何地方 更新:对我来说,最大的困难是找出如何仅在主应用程序(蓝色区域)中捕获单击事件。这对组件来说是错误的吗?对话框应该

我有一个Angular应用程序,它有一个弹出对话框,用户可以在其中输入一些信息。我希望在单击应用程序中的任何区域(弹出对话框除外)时关闭或隐藏此对话框。这样,用户可以根据需要输入数据,只有在弹出对话框外部单击时,才会关闭该对话框

我可以使用
(mousleave)
事件,但我只希望在用户单击主应用程序中的某个位置时隐藏弹出对话框(而不是弹出对话框)。在下图中,这意味着蓝色区域的任何地方


更新:对我来说,最大的困难是找出如何仅在主应用程序(蓝色区域)中捕获单击事件。

这对组件来说是错误的吗?对话框应该是一个固定的全屏元素的顶部,如

<div class="overlayer" style="display: fixed; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.6); z-index: 9999" onclick="closeYourDialog()">
    <div class="your-dialog">
        ...
    </div>
</div>

...

如果您不喜欢覆盖层,您可以将不透明度设置为0。

这对您的组件来说是错误的吗?对话框应该是一个固定的全屏元素的顶部,如

<div class="overlayer" style="display: fixed; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.6); z-index: 9999" onclick="closeYourDialog()">
    <div class="your-dialog">
        ...
    </div>
</div>

...

如果您不喜欢“覆盖层”,可以将“不透明度”设置为0。

您可以将此对话框用作模式(可能是引导),该模式在内部将使用背景收听,并在单击“外部”时关闭模式

如果您想通过自己的HTML实现,可以创建自己的背景,并在背景上添加一个单击事件侦听器。诀窍是防止单击事件从对话框中冒泡出来

为背景添加一个div,如:

<div *ngIf="customDialogOpen" class="customBackdrop" (click)="customDialogOpen = false">

<dialog-component *ngIf="customDialogOpen"></dialog-component>


.customBackdrop {
  bottom: 0;
  left: 0;
  margin: auto;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 999;  // lower than the z index of your dialog but higher than rest of the document
}
更新

我的答案是将背景添加为同级,@incNick给出了一个更好的方法,你可以将整个对话框作为一个固定元素与背景一起打开,只需添加一个额外的div,停止所有点击事件的传播

<div class="customBackdrop" *ngIf="customDialogOpen" (click)="customDialogOpen = false">
    <div (click)="$event.stopPropagation()">
       <dialog-component></dialog-component>
    </div>
</div>


注意:如果您有一个处理传播的外部div,则无需在此解决方案或第一个解决方案中添加额外的
stopPropagation()

您可以将此对话框用作模式(可能是引导),当您单击外部时,内部将使用背景来监听并关闭模式

如果您想通过自己的HTML实现,可以创建自己的背景,并在背景上添加一个单击事件侦听器。诀窍是防止单击事件从对话框中冒泡出来

为背景添加一个div,如:

<div *ngIf="customDialogOpen" class="customBackdrop" (click)="customDialogOpen = false">

<dialog-component *ngIf="customDialogOpen"></dialog-component>


.customBackdrop {
  bottom: 0;
  left: 0;
  margin: auto;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 999;  // lower than the z index of your dialog but higher than rest of the document
}
更新

我的答案是将背景添加为同级,@incNick给出了一个更好的方法,你可以将整个对话框作为一个固定元素与背景一起打开,只需添加一个额外的div,停止所有点击事件的传播

<div class="customBackdrop" *ngIf="customDialogOpen" (click)="customDialogOpen = false">
    <div (click)="$event.stopPropagation()">
       <dialog-component></dialog-component>
    </div>
</div>


注意:如果您有一个处理传播的外部div,则无需在此解决方案或第一个解决方案中添加额外的
stopPropagation()

您可以创建一个
clickout
指令,以便您可以侦听单击事件并检查其目标是否是您的目标。您可以签出以创建自定义指令

在指令中,您可以使用
@HostListener()
侦听单击事件:

@Directive({
  selector: '[clickOutside]'
})
export class ClickedOutsideDirective{

    @Output()
    clickOutside: EventEmitter<Event> = new EventEmitter<Event>();

    @HostListener('document:click', ['$event'])
    onClick(event) {
        if(!this.elemRef.nativeElement.contains(event.target)) {
        // Cliecked Outside
         this.clickOutside.emit(event);
        }
    }

    constructor(private elemRef: ElementRef) {
    }
}

您可以创建一个
ClickOutside
指令,以便您可以监听click事件并检查其目标是否是您的目标。您可以签出以创建自定义指令

在指令中,您可以使用
@HostListener()
侦听单击事件:

@Directive({
  selector: '[clickOutside]'
})
export class ClickedOutsideDirective{

    @Output()
    clickOutside: EventEmitter<Event> = new EventEmitter<Event>();

    @HostListener('document:click', ['$event'])
    onClick(event) {
        if(!this.elemRef.nativeElement.contains(event.target)) {
        // Cliecked Outside
         this.clickOutside.emit(event);
        }
    }

    constructor(private elemRef: ElementRef) {
    }
}

我们可以看到对话框在标记和/或代码中的显示方式吗?它是一个角度组件吗?弹出对话框是一个单独的组件,我将其设置为
ngClass='show
,这是一个引导类。对话框可以自行关闭,还是由父级负责关闭?我们可以看到对话框在标记和/或代码中的显示方式吗?它是一个角度组件吗?弹出对话框是一个单独的组件,我将其设置为
ngClass='show
,这是一个引导类对话框可以自行关闭,还是由父级负责关闭?