fix(platform-browser): simple version of zone aware addEventListener#18993
fix(platform-browser): simple version of zone aware addEventListener#18993JiaLiPassion wants to merge 2 commits intoangular:masterfrom
Conversation
There was a problem hiding this comment.
Could we turn the events into map. Calling filter all the time has negative perf implication. This would be faster. blackListMap.hasOwnProperty(eventName)
There was a problem hiding this comment.
@mhevery , got it, I will use map to check.
There was a problem hiding this comment.
PERF: We should delay checking if it is black-listed until after we know we have Zone.
There was a problem hiding this comment.
@mhevery , ok, I will check it after zoneJsLoaded is true.
|
@mhevery , I have updated the commits.
please review. |
There was a problem hiding this comment.
Sorry I meant that you would convert the array into the map, rather than expect that the data is provided as a map.
There was a problem hiding this comment.
@mhevery , got it, sorry for misunderstanding, I have updated the source, please review.
|
@mhevery , I have updated the source and write a sample code to describe how to set Please review. |
|
@mhevery , I found a bug which is the same one with angular/zone.js#839, the issue can be described as the following case. const handler1 = (e: any)=> {
// handler remove itself
remover1 && remover1();
};
const handler2 = (e: any) => {
console.log('handler2');
};
const manager = new EventManager([domEventPlugin], new FakeNgZone());
remover1 = manager.addEventListener(element, 'click', handler1);
remover2 = manager.addEventListener(element, 'click', handler2);
getDOM().dispatchEvent(element, dispatchedEvent);in previous version, The modified code in // a global listener to handle all dom event,
// so we do not need to create a closure everytime
const globalListener = function(event: Event) {
const symbolName = symbolNames[event.type];
if (!symbolName) {
return;
}
const taskDatas: TaskData[] = this[symbolName];
if (!taskDatas) {
return;
}
const args: any = [event];
if (taskDatas.length === 1) {
// if taskDatas only have one element, just invoke it
const taskData = taskDatas[0];
if (taskData.zone !== Zone.current) {
// only use Zone.run when Zone.current not equals to stored zone
return taskData.zone.run(taskData.handler, this, args);
} else {
return taskData.handler.apply(this, args);
}
} else {
// copy tasks as a snapshot to avoid event handlers remove
// itself or others
const copiedTasks = taskDatas.slice();
for (let i = 0; i < copiedTasks.length; i++) {
const taskData = copiedTasks[i];
if (taskData.zone !== Zone.current) {
// only use Zone.run when Zone.current not equals to stored zone
taskData.zone.run(taskData.handler, this, args);
} else {
taskData.handler.apply(this, args);
}
}
}
};it is the same with angular/zone.js#839 , please review. |
|
Little late to the party, but doesn't the introduction of a |
|
|
@JiaLiPassion I guess sample code will be fine: Let's say your And your Then even though you call |
|
@PierreDuc , got it, thank you, I can fix this one. |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: 18753
What is the new behavior?
EventHandler will run into the correct zone which will be the zone when
addEventListeneris invokedDoes this PR introduce a breaking change?
Other information
fix #18753.
Add a simple version of zone aware addEventListener.
globalEventHandlerto handle all events to avoid creating to many closure function.zonewhenaddEventListener, but for better performance, we don't usezone.jsmechanism toscheduleEventTask, soZoneSpec.onInvokeTask,ZoneSpec.onScheduleTask,ZoneSpec.onCancelTaskwill not be invoked.addEventListener, if theZone.currentisngZone, we just usenative addEventListenerfor better performance (which will be the most cases).blackListedEventsso user can decide which events they want to run outside of ngZone.Here is a sample to run all
scrollevent handler outside of ngZone.@mhevery , please review.