【问题标题】:Angular2 Custom EventsAngular2 自定义事件
【发布时间】:2016-07-31 10:31:11
【问题描述】:

我正在尝试找出如何处理由 Angular 之外的东西发出的自定义 DOM 事件,例如以下内容:

document.querySelector('my-custom-element').dispatchEvent(new Event('my.customEvent'));

到目前为止,我已尝试注册一个新的 EventManagerPlugin,它支持以“my.”开头的所有内容。但是如果我打印出所有“正常”事件(如“点击”和“提交”)所产生的所有事件;但没有我的自定义事件。

html:

<my-custom-element (my.customEvent)="handleCustomEvent($event)"></my-custom-element>

ts:

supports(eventName: string):boolean {
    var ret = false;
    if (eventName.indexOf('my.') === 0) {
        ret = true;
    }
    console.log('supports event?', eventName, ret);
    return ret;
}

console.log 行仅打印本机事件和 ng*events,但不打印我的自定义事件 :(

编辑固定解决方案 我已经在组件内移动了 (my.customEvent) 并且日志显示了自定义事件。 通过在 EventManagerPlugin 中使用自定义 eventHandler 将外部事件绑定到 angular2 内部事件,同时将 2 分开 关联代码

addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
    let zone = this.manager.getZone();

    // Entering back into angular to trigger changeDetection
    var outsideHandler = (event: any) => {
        zone.run(() => handler(event));
    };

    // Executed outside of angular so that change detection is not constantly triggered.
    var addAndRemoveHostListenersForOutsideEvents = () => {
        this.manager.addEventListener(element, 'external.' + eventName, outsideHandler);
    }
    return this.manager.getZone().runOutsideAngular(addAndRemoveHostListenersForOutsideEvents);
}

通过 DOM 触发事件:

document.querySelector('my-custom-element').dispatchEvent(new Event('external.my.customEvent'));

现在您可以从 DOM 中触发一个事件,该事件被推送到 angular2 世界中,并且可以从组件内部处理代码。

【问题讨论】:

  • 你能提供一些能重现你的问题的插件吗?这是示例plnkr.co/edit/qvtmFfR9TEp0dxaDsaOY?p=preview 请参阅控制台
  • @yurzui:感谢您的支持;要使“支持”部分起作用,我唯一要做的就是将事件移到 HTML 中。 eventlistener 不会监听 dispatchEvent 触发的事件。仍然对如何编写它感到困惑,以便它在 angular2 之外侦听,但从 angular2 内部处理。

标签: javascript angular


【解决方案1】:

尝试扩展DomEventsPlugin,例如:

import {DomEventsPlugin} from 'angular2/platform/common_dom';
// Have to pull DOM from src because platform/common_dom returns DOM as null.
// I believe its a TS bug.
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {Injectable} from 'angular2/core';
import {noop} from 'angular2/src/facade/lang';

@Injectable()
export class DOMOutsideEventPlugin extends DomEventsPlugin {
  eventMap: Object = {
    "clickOutside": "click",
    "mousedownOutside": "mousedown",
    "mouseupOutside": "mouseup",
    "mousemoveOutside": "mousemove"
  }
  supports(eventName: string): boolean {
    return this.eventMap.hasOwnProperty(eventName);
  }

  addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
    var zone = this.manager.getZone();
    var documentEvent = this.eventMap[eventName];

    // Entering back into angular to trigger changeDetection 
    var outsideHandler = (event) => {
        zone.run(() => handler(event))
    };

    // Executed outside of angular so that change detection is not constantly triggered.
    var addAndRemoveHostListenersForOutsideEvents = () => {
      DOM.onAndCancel(DOM.getGlobalEventTarget('document'), documentEvent,
        (event) => {
          let current = event.target;
          // if the element/event is propagating from the element its bound to, don't handle it.
          if (current.parentNode && current !== element) {
              outsideHandler(event);
        }
      });
    }
    return this.manager.getZone().runOutsideAngular(addAndRemoveHostListenersForOutsideEvents);
  }

  addGlobalEventListener(target: string, eventName: string, handler: Function): Function {
    var element = DOM.getGlobalEventTarget(target);
    var zone = this.manager.getZone();
    var outsideHandler = (event) => zone.run(() => handler(event));

    if ((target === "document") || (target === "window" )) {
      return noop;
    }
    return this.manager.getZone().runOutsideAngular(
        () => DOM.onAndCancel(element, eventName, outsideHandler)
    );
  }
}

来源:https://medium.com/@TheLarkInn/creating-custom-dom-events-in-angular2-f326d348dc8b#.so0jvssnz

【讨论】:

  • 这段代码真的很旧,但我已经把它移植到了RC4;不幸的是,supports 方法仍然只打印本地和特定于角度的事件;在那种情况下有效,但不是我的;我想在哪里使用真正的自定义事件。
猜你喜欢
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-03
  • 2019-06-25
  • 1970-01-01
相关资源
最近更新 更多