javascript - 你能阻止 Angular 组件的主机点击被触发吗?

标签 javascript angular angular-template

我正在创建一个包装原生 <button> 的 Angular 组件具有一些附加功能的元素。如果按钮被禁用并且我想复制相同的功能,则按钮不会触发点击事件。即,给定:

<my-button (click)="onClick()" [isDisabled]="true">Save</my-button>

有没有办法my-button防止onClick()从被调用?

在 Angular 中,您可以通过这种方式监听主机点击事件,并停止该事件的传播:

//Inside my-button component
@HostListener('click', ['$event'])
onHostClick(event: MouseEvent) {
  event.stopPropagation();
}

这可以防止事件冒泡到祖先元素,但不会停止内置的 (click)在同一宿主元素上触发的输出。

有没有办法做到这一点?


编辑 1: 我现在解决这个问题的方法是使用一个名为“onClick”的不同输出,消费者必须知道使用“onClick”而不是“click”。这并不理想。

编辑 2:单击源自 <button> 的事件元素已成功停止。但是,如果您像我一样将元素放入按钮标记内,则这些目标上的单击事件会向上传播到主机。嗯,应该可以将按钮包装在另一个停止传播的元素中......

最佳答案

您可以执行以下操作:

  • 重新定义组件的click事件,点击按钮时触发该事件
  • 在组件主机上设置 CSS 样式 pointer-events: none
  • 在按钮上设置 CSS 样式 pointer-events: auto
  • 在按钮单击事件处理程序上调用 event.stopPropagation()

如果您需要处理组件内部其他元素的点击事件,请为它们设置样式属性pointer-events: auto,并调用event.stopPropagation() 在他们的点击事件处理程序中。

您可以测试this stackblitz中的代码.

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

@Component({
  selector: 'my-button',
  host: {
    "[style.pointer-events]": "'none'"
  },
  template: `
    <button (click)="onButtonClick($event)" [disabled]="isDisabled" >...</button>
    <span (click)="onSpanClick($event)">Span element</span>`,
  styles: [`button, span { pointer-events: auto; }`]
})
export class MyCustomComponent {

  @Input() public isDisabled: boolean = false;
  @Output() public click: EventEmitter<MouseEvent> = new EventEmitter();

  onButtonClick(event: MouseEvent) {
    event.stopPropagation();
    this.click.emit(event);
  }

  onSpanClick(event: MouseEvent) {
    event.stopPropagation();
  }
}

更新:

由于按钮可以包含 HTML 子元素(spanimg 等),您可以添加以下 CSS 样式以防止点击被传播到 parent :

:host ::ng-deep button * { 
  pointer-events: none; 
}

感谢@ErikWitkowski对于 his comment在这种特殊情况下。参见 this stackblitz用于演示。

关于javascript - 你能阻止 Angular 组件的主机点击被触发吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49415692/

相关文章:

javascript - 显示来自两个下拉菜单的图像

javascript - 如何显示带有id的元素并隐藏其他元素

angular - 在测试之前如何等待 async ngOninit 完成

angular - 我如何使用 "*ngIf else"?

javascript - 如何将换行符从 HTML div 复制到 jQuery 中的文本区域?

javascript - 使用 Axios 删除 React 中的请求

unit-testing - Angular 2 RC 如何对可观察的进行单元测试

javascript - Angular 2 : check empty form if radio button is set

html - Angular 7 : Dynamically generate template

模板内的 Angular 注释属性