防止 Angular HostListener 传播到父组件

Posted

技术标签:

【中文标题】防止 Angular HostListener 传播到父组件【英文标题】:Prevent Angular HostListener propagation to parent component 【发布时间】:2020-01-11 02:54:20 【问题描述】:

问题

我的一个组件设置了HostListener 绑定:

@HostListener('window:resize', ['$event']) callback ($event) 
   // D3Js tasks here …

目前,当调用监听器时,父组件重新评估其模板,就好像父组件确实响应了某个子组件的output。 但是侦听器执行的任务不需要父组件的任何更新。

我希望监听器可以在不通知父组件的情况下执行。

在 Angular在这种情况下的某处可以防止这种冒泡行为

尝试

$event.stopPropagation()$event.stopImmediatePropagation() 都没有帮助,可能是因为这种行为与 Angular 内部结构有关。 将 HostListener 声明留空(注释掉包含的指令)不会改变任何东西,我认为这表明 HostListener 声明是这里的罪魁祸首。

我目前的解决方案是在组件构造函数中直接从原生 DOM 事件(不依赖 Angular)中创建一个 observable:

this.onResizeSub = Observable
    .fromEvent(window, 'resize', null, null)
    .subscribe( () => …);
);

注意事项:使用 Angular v4.4.2,到处更改检测 OnPush 策略。

【问题讨论】:

【参考方案1】:

不幸的是,Angular 目前似乎不支持此功能。有一个功能请求,但看起来我们不会很快看到这个:https://github.com/angular/angular/issues/9587, https://github.com/angular/angular/issues/10990

执行顺序是红鲱鱼 - 同一元素上的事件传播到多个侦听器的顺序当前未定义。这是目前的设计。

您的问题是向侦听器公开的事件是真正的 DOM 事件,并且在提供的事件上调用 stopImmediatePropagation() 会停止执行在此元素上注册的其他侦听器。但是,由于通过 Angular 注册的所有监听器都由一个 dom 监听器代理(出于性能原因),因此在此事件上调用 stopImmediatePropagation 无效。

【讨论】:

以上是关于防止 Angular HostListener 传播到父组件的主要内容,如果未能解决你的问题,请参考以下文章

Angular - 创建通用装饰器包装 @HostListener

Angular 8 @HostListener('window:scroll', []) 不工作

Angular - HostListener 指令和传递值

Angular HostListener 只捕获一个事件

打字稿 | JavaScript | Angular 2:动态设置@HostListener 参数

Angular12 - 使用 @HostBinding 或 @HostListener 而不是 `host` 元数据属性