我正在使用Angular6。我有一个带有click事件的表行(<TR>
)。出于测试目的,我们只说事件打印“嘎嘎!”到控制台。这是HTML:
<tr *ngFor="let t of things" (click)="quack()">
...
</tr>
在组件中:
quack() {
console.log('quack!');
}
现在,在此行中,我有一个复选框。这是一个Bootstrap 4自定义复选框,但我认为这对我需要解决的问题并不重要。该复选框具有一个自定义指令,该指令添加了 change 事件处理程序(而不是 click 事件)。 HTML的简化版本是:
<tr *ngFor="let t of things" (click)="quack()">
...
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="cb{{t.id}}" name="cb{{t.id}}"
[my-directive]="b.somedata">
<label class="custom-control-label" for="cb{{t.id}}"> </label>
</div>
...
</tr>
在my-directive指令代码中:
@HostListener('change') onChange() {
// do some stuff...
}
我想要发生的事情是quack()
函数在任何人单击该行时触发,除非他们单击该复选框。当他们选中或取消选中复选框时,我希望触发自定义指令中的onChange()
函数,并且我不想发出嘎嘎声。
“嘎嘎!”每次单击该行,控制台中都会出现一次,这是正确的。奇怪的是,当我单击复选框时,我得到两个 嘎嘎声,然后触发onChange()
处理程序。我想要零个嘎嘎,我希望有一个,但是我有两个!
我在(click)="$event.stopPropagation();"
元素中添加了<input>
,以为这可以解决问题。当我单击复选框时,它使我跌至只有一个嘎嘎声。我想调零。 如何防止单击复选框传播触发click()
的{{1}}事件?
答案 0 :(得分:3)
我错误地认为它是Bootstrap 4自定义复选框不是很重要-实际上,这是解决我的问题的关键。在Bootstrap 4的这种用法中,<input>
本身是不可见的!您在屏幕上看到的类似于复选框的内容实际上是由CSS生成的。因此,click
事件首先不属于该<input>
元素。
为解决此问题,我将(click)="$event.stopPropagation();"
移到了包装自定义复选框的<div>
元素上,如下所示:
<tr *ngFor="let t of things" (click)="quack()">
...
<div class="custom-control custom-checkbox" (click)="$event.stopPropagation();">
<input type="checkbox" class="custom-control-input" id="cb{{t.id}}" name="cb1"
[my-directive]="b.somedata">
<label class="custom-control-label" for="cb{{t.id}}"> </label>
</div>
...
</tr>
如果我使用的是普通复选框而不是这些Bootstrap 4自定义复选框,那么ConnorsFan提到的两种解决方案都可以很好地工作。