2016-07-31 104 views
0

我試圖找出如何處理事情的角度向外發射的自定義DOM事件,例如以下:Angular2自定義事件

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

到目前爲止,我曾嘗試註冊一個新的EventManagerPlugin支持一切以'我的'開頭。但是如果我打印出所有'正常'事件發生的事件,如「點擊」和「提交」都打印出來;但沒有我的自定義事件。

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 *事件,但不是我的自定義事件:(

編輯固定解決方案 我已將組件(my.customEvent)移動到組件中並且日誌顯示了自定義事件。 綁定外部事件到angular2內部事件而分離該2是通過在EventManagerPlugin Relevate專門代碼

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')); 

現在可以從被推入到angular2世界中的DOM觸發事件,並且可以從組件內處理代碼。

+0

你能提供一些plunker再現問題了嗎?這裏是示例https://plnkr.co/edit/qvtmFfR9TEp0dxaDsaOY?p=preview請參閱控制檯 – yurzui

+0

@yurzui:謝謝你的闖入者;爲了使「支持」部分能夠工作,我唯一需要做的就是將事件移動到HTML中。 雖然eventlistener不會偵聽由dispatchEvent觸發的事件。仍然對如何編寫它感到困惑,所以它在angular2外部偵聽,但在angular2內部處理。 –

回答

0

儘量延長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

+0

這段代碼真的很老,但我把它移植到了RC4上;不幸的是,支持方法仍然只打印本地和特定角度的事件;在那種情況下工作,但不是我的;我想使用真正的自定義事件。 –