简体   繁体   English

首次单击后,Angular2删除单击事件绑定

[英]Angular2 remove click event binding after first click

In my application I have a button with a click even on it: 在我的应用程序中,我有一个按钮,甚至可以点击它:

<button class="btn btn-default" (click)="doSomething()">

From within the doSomething method, is there any way to remove the (click) event from the button (so the user can't trigger the functionnality anymore?). doSomething方法中,有没有办法从按钮中删除(click)事件(这样用户就不能再触发函数?)。

I tried to set a disabled prop on the button but it doesn't change Angular2 behavior. 我试图在按钮上设置一个禁用的道具,但它不会改变Angular2的行为。

I tryed to use (click)="doSomething($event) and then 我尝试使用(click)="doSomething($event)然后

doSomething($event) {
  // My method logic goes here
  ...
  ...
  console.log('Method Logic');

  //Attempt to overwrite click event
  let target = event.target || event.srcElement || event.currentTarget;
  this.renderer.listen(target, 'click', (event) => {
      console.log('clic block');
    });
}

But It doesn't "replace" the click event. 但它不会“替换”click事件。 So after that, on click, both original logic and the "click block" console log are triggered! 因此,在此之后,单击时,将触发原始逻辑和“单击块”控制台日志!

Method 1 : 方法1

You can set a boolean variable, so if the user calls the function, boolean value changes and the user will be able to call the function on click again but actually nothing will happen. 你可以设置一个boolean变量,所以如果用户调用该函数, boolean值会改变,用户可以再次点击该函数,但实际上什么都不会发生。

bool: boolean = true;

doSomething($event) {
  if (this.bool) {
    // My method logic goes here
    ...
    ...
    console.log('Method Logic');
    this.bool = false;
  }
}

Method 2 : 方法2

You can add a condition to your html component, if specified variable (in this case bool ) is true, the function is going to be executed, but only once because the bool variable will be set to false and the click function will execute nothing (null) from now on. 您可以为html组件添加一个条件,如果指定的变量(在本例中为bool )为true,则该函数将被执行,但只执行一次,因为bool变量将设置为false并且click函数将不执行任何操作(从现在开始。

bool: boolean = true;

doSomething($event) {
  // My method logic goes here
  ...
  ...
  console.log('Method Logic');
  this.bool = false;
}

(click)="bool ? doSomething($event) : null"

The downside of just adding a guard variable for the execution is that the actual event listener is still in place and will trigger Angular's change detection when clicked, even though it doesn't do anything. 为执行添加一个保护变量的缺点是实际的事件监听器仍然存在并且在点击时会触发Angular的变化检测,即使它没有做任何事情。

To actually remove the event listener, you have to add it via the component's Renderer . 要实际删除事件侦听器,必须通过组件的Renderer添加它。 This will return a function that removes the event listener when called: 这将返回一个函数,该函数在调用时删除事件侦听器:

import {Component, AfterViewInit, Renderer, ViewChild, ElementRef} from '@angular/core';

@Component({
  template: `<button #button>...</button>`
})
export class SampleComponent implements AfterViewInit {

  @ViewChild('button') button: ElementRef;
  private cancelClick: Function;

  constructor(private renderer: Renderer) {}

  ngAfterViewInit() {
    this.cancelClick = this.renderer.listen(this.button.nativeElement, 'click',
      ($event: any) => this.handleClick($event));
  }

  handleClick($event: any) {
    this.cancelClick();
    // ...
  }
}

If your goal is to just remove the event listener when the event is fired for the first time, this can be implemented as a plugin to Angular's event system. 如果您的目标是在第一次触发事件时删除事件侦听器,则可以将其实现为Angular事件系统的插件。 I added it as a part of my ng2-events utility library [source] , which lets you now do the following: 我将它添加为我的ng2-events实用程序库[source]的一部分 ,它现在允许您执行以下操作:

<button (once.click)="handleClick($event)">...</button>

For people dealing with Observable / Subject for handling some events : 对于处理Observable / Subject以处理某些事件的人:

<button (click)="clickEvents$.next($event)">
class MyComponent {
  clickEvents$ = new Subject<MouseEvent>();
  firstClick$ = this.clickEvents.take(1); // Observable of first click
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM