角。绑定事件只有一次(在第一次初始化时)

时间:2017-12-25 21:37:13

标签: angular addeventlistener ngoninit

假设我想在每次点击<a>代码时提醒用户。

document.querySelector('body').addEventListener('click', function (event : any) {
            if (event.target.tagName === 'A') {
                event.preventDefault();
                alert('Congratulations! A tag clicked!!!');
            }
        });

如果我将此绑定放在constructor中(在ngOnInit()中),每次进入此组件(路由器链接)时,我都会有新的绑定(以及另一个警报)。
在第一个init上只绑定一次的方法是什么?

与此同时,我在removeEventListener()中使用ngOnDestroy()。这看起来很难看。还有什么更好的吗?

1 个答案:

答案 0 :(得分:1)

您似乎需要检查元素上是否已存在所需的事件侦听器。请参阅:How to check whether dynamically attached event listener exists or not?

基于this answer我会建议使用这样的东西(至少对我有用):

function showAlert(evt) {
  evt.preventDefault();
  alert('Congratulations! A tag clicked!!');
}

  const aTags = document.querySelectorAll('a');
  for (const i in aTags) {
    const element = aTags[i];
      if (element instanceof Element && element.getAttribute('listener') !== 'true') {
        element.addEventListener('click', showAlert);
        element.setAttribute('listener', 'true');
    }
  }

如果需要将事件侦听器绑定到整个实体,就像在示例中一样,您可以使用静态变量。只需在组件的开头创建一个,并在绑定事件侦听器之前检查它的值。 E.g:

export class CongratulationsComponent implements OnInit {
  static flag = true;
  constructor() {}

  ngOnInit() {
    if (CongratulationsComponent.flag) {
      document.querySelector('body').addEventListener('click', function (event: any) {
        if (event.target.tagName === 'A') {
          event.preventDefault();
          alert('Congratulations! A tag clicked!!!');
        }
      });
      CongratulationsComponent.flag = false;
    }
  }
}