PR Close #20538
This commit is contained in:
parent
2a9d2bacd5
commit
a740e4f00a
|
@ -203,16 +203,26 @@ export class DomEventsPlugin extends EventManagerPlugin {
|
||||||
// just call native removeEventListener
|
// just call native removeEventListener
|
||||||
return target[NATIVE_REMOVE_LISTENER].apply(target, [eventName, callback, false]);
|
return target[NATIVE_REMOVE_LISTENER].apply(target, [eventName, callback, false]);
|
||||||
}
|
}
|
||||||
|
// fix issue 20532, should be able to remove
|
||||||
|
// listener which was added inside of ngZone
|
||||||
|
let found = false;
|
||||||
for (let i = 0; i < taskDatas.length; i++) {
|
for (let i = 0; i < taskDatas.length; i++) {
|
||||||
// remove listener from taskDatas if the callback equals
|
// remove listener from taskDatas if the callback equals
|
||||||
if (taskDatas[i].handler === callback) {
|
if (taskDatas[i].handler === callback) {
|
||||||
|
found = true;
|
||||||
taskDatas.splice(i, 1);
|
taskDatas.splice(i, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (found) {
|
||||||
if (taskDatas.length === 0) {
|
if (taskDatas.length === 0) {
|
||||||
// all listeners are removed, we can remove the globalListener from target
|
// all listeners are removed, we can remove the globalListener from target
|
||||||
underlyingRemove.apply(target, [eventName, globalListener, false]);
|
underlyingRemove.apply(target, [eventName, globalListener, false]);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// not found in taskDatas, the callback may be added inside of ngZone
|
||||||
|
// use native remove listener to remove the calback
|
||||||
|
target[NATIVE_REMOVE_LISTENER].apply(target, [eventName, callback, false]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,6 +255,46 @@ export function main() {
|
||||||
expect(receivedEvents).toEqual([]);
|
expect(receivedEvents).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to remove event listener which was added inside of ngZone', () => {
|
||||||
|
const Zone = (window as any)['Zone'];
|
||||||
|
|
||||||
|
const element = el('<div><div></div></div>');
|
||||||
|
getDOM().appendChild(doc.body, element);
|
||||||
|
const dispatchedEvent = getDOM().createMouseEvent('click');
|
||||||
|
let receivedEvents: any[] /** TODO #9100 */ = [];
|
||||||
|
let receivedZones: any[] = [];
|
||||||
|
const handler1 = (e: any /** TODO #9100 */) => {
|
||||||
|
receivedEvents.push(e);
|
||||||
|
receivedZones.push(Zone.current.name);
|
||||||
|
};
|
||||||
|
const handler2 = (e: any /** TODO #9100 */) => {
|
||||||
|
receivedEvents.push(e);
|
||||||
|
receivedZones.push(Zone.current.name);
|
||||||
|
};
|
||||||
|
const manager = new EventManager([domEventPlugin], new FakeNgZone());
|
||||||
|
|
||||||
|
let remover1 = null;
|
||||||
|
let remover2 = null;
|
||||||
|
// handler1 is added in root zone
|
||||||
|
Zone.root.run(() => { remover1 = manager.addEventListener(element, 'click', handler1); });
|
||||||
|
// handler2 is added in 'angular' zone
|
||||||
|
Zone.root.fork({name: 'fakeAngularZone', properties: {isAngularZone: true}}).run(() => {
|
||||||
|
remover2 = manager.addEventListener(element, 'click', handler2);
|
||||||
|
});
|
||||||
|
getDOM().dispatchEvent(element, dispatchedEvent);
|
||||||
|
expect(receivedEvents).toEqual([dispatchedEvent, dispatchedEvent]);
|
||||||
|
expect(receivedZones).toEqual([Zone.root.name, 'fakeAngularZone']);
|
||||||
|
|
||||||
|
receivedEvents = [];
|
||||||
|
remover1 && remover1();
|
||||||
|
remover2 && remover2();
|
||||||
|
getDOM().dispatchEvent(element, dispatchedEvent);
|
||||||
|
// handler1 and handler2 are added in different zone
|
||||||
|
// one is angular zone, the other is not
|
||||||
|
// should still be able to remove them correctly
|
||||||
|
expect(receivedEvents).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should run blackListedEvents handler outside of ngZone', () => {
|
it('should run blackListedEvents handler outside of ngZone', () => {
|
||||||
const Zone = (window as any)['Zone'];
|
const Zone = (window as any)['Zone'];
|
||||||
const element = el('<div><div></div></div>');
|
const element = el('<div><div></div></div>');
|
||||||
|
|
Loading…
Reference in New Issue