Angular2指令修改点击处理

Posted

技术标签:

【中文标题】Angular2指令修改点击处理【英文标题】:Angular2 Directive to modify click handling 【发布时间】:2016-11-23 19:24:30 【问题描述】:

我正在尝试编写一个 Angular2 属性指令来修改某些元素的行为。更具体地说,我想将属性应用于具有点击处理程序的某些元素,并防止绑定函数在某些条件下执行。

所以现在我有一个元素,例如:

<button (click)="onClick(param1, param2)"></button>

onClick 是在承载按钮元素的组件上声明的函数。

我想做的是这样写:

<button (click)="onClick(param1, param2)" online-only></button>

并有一个类似的指令:

@Directive(
  selector: '[online-only]',
)
export class OnlineOnlyDirective 
  @HostListener('click', ['$event']) 
  onClick(e) 
    if(someCondition)
      e.preventDefault();
      e.stopPropagation();
    
  

但是单击处理程序首先执行,因此我的指令没有机会停止执行。

我想到的第二种方法是用我自己的处理程序替换(单击),例如([onlineClick]="onClick")并在指令认为合适时执行传递的函数,但是这样我不能将参数传递给 onClick 函数和看起来有点奇怪。

你对做这样的事情有什么想法吗?

【问题讨论】:

【参考方案1】:

我不知道如何强制 Angular 首先执行某个事件处理程序。一种解决方法可能是使用自定义事件,例如:

<button (myClick)="onClick(param1, param2)" online-only></button>
@Directive(
  selector: '[myClick]',
)
export class OnlineOnlyDirective 
  @Output() myClick: EventEmitter = new EventEmitter();
  @HostListener('click', ['$event']) 
  onClick(e) 
    if(someCondition)
      e.preventDefault();
      e.stopPropagation();
     else 
      this.myClick.next(e);
    
  

【讨论】:

是的,采用我描述的第二种方法要好得多。使用 EventEmitter 而不是传入要调用的函数会有所不同。第一种方法会更优雅,但正如你所说的那样,angular2 可能不支持。 只是好奇选择器是否应该是 '[online-only]' ?试图弄清楚该指令发生了什么。 我不知道online-only是否或如何与问题相关 我认为选择器应该是selector: '[online-only]',。它是拉入此指令的粘合剂。【参考方案2】:

到目前为止,这是不可能的(仅使用(单击)绑定)。这是因为通过 Angular -> 通过(单击)绑定 @HostListner 注册的所有事件都通过单个侦听器进行代理。这就是为什么在这种情况下调用 stopPropagation 或更正确的方法 stopImmediatePropagation 不起作用的原因,因为您不再有单独的事件侦听器。更多详情请参考此问题:https://github.com/angular/angular/issues/9587。

【讨论】:

【参考方案3】:

我最近经历了一些我想做的类似事情,但建议的答案没有奏效,可能是因为我在自定义组件上有点击处理程序。这就是我所做的。

<button (myClick)="onClick(param1, param2)" online-only></button>

或者

<my-cmp (myClick)="onClick(param1, param2)" online-only></my-cmp>

指令可能如下所示:

@Directive(
   selector: '[online-only]',
)
export class OnlineOnlyDirective implements OnInit 
   constructor(private el: ElementRef)  

   ngOnInit() 
      if (someCondition) 
         this.el.nativeElement.removeAllListeners('click');
      
   

这将移除组件或元素上的点击事件监听器。这不会是反应性的,因此如果someCondition 发生变化,则必须有一种方法可以将点击侦听器放回原处。不过我不需要这个用例。

更新

这在开发中对我有用,但在生产环境中缩小代码时对我不起作用。

【讨论】:

以上是关于Angular2指令修改点击处理的主要内容,如果未能解决你的问题,请参考以下文章

Angular2拖放目标

具有范围的 Angular2 指令

Angular2更新指令输入

angular2 自定义指令输入语法

从属性到结构,带你深入理解 Angular2 两大类型指令!

Angular2 指令监听父组件回调或更改