New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(platform-browser): simple version of zone aware addEventListener #18993
Conversation
if (!blackListedEvents) { | ||
return false; | ||
} | ||
return blackListedEvents.filter(blackListedEvent => blackListedEvent === eventName).length > 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mhevery , got it, I will use map to check.
}; | ||
// if zonejs is loaded and current zone is not ngZone | ||
// we keep Zone.current on target for later restoration. | ||
const isBlackListed = isBlackListedEvent(eventName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PERF: We should delay checking if it is black-listed until after we know we have Zone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mhevery , ok, I will check it after zoneJsLoaded
is true.
@mhevery , I have updated the commits.
please review. |
const NATIVE_ADD_LISTENER = 'addEventListener'; | ||
const NATIVE_REMOVE_LISTENER = 'removeEventListener'; | ||
|
||
const blackListedMap: {[key: string]: string} = Zone && Zone[__symbol__('BLACK_LISTED_EVENTS')]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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
addEventListener
is invokedDoes this PR introduce a breaking change?
Other information
fix #18753.
Add a simple version of zone aware addEventListener.
globalEventHandler
to handle all events to avoid creating to many closure function.zone
whenaddEventListener
, but for better performance, we don't usezone.js
mechanism toscheduleEventTask
, soZoneSpec.onInvokeTask
,ZoneSpec.onScheduleTask
,ZoneSpec.onCancelTask
will not be invoked.addEventListener
, if theZone.current
isngZone
, we just usenative addEventListener
for better performance (which will be the most cases).blackListedEvents
so user can decide which events they want to run outside of ngZone.Here is a sample to run all
scroll
event handler outside of ngZone.@mhevery , please review.