-
Notifications
You must be signed in to change notification settings - Fork 27.5k
fix(rootScope): $watchCollection returns in oldCollection a copy of the ... #5688
fix(rootScope): $watchCollection returns in oldCollection a copy of the ... #5688
Conversation
…he former array data related to angular#1751 When watching arrays, $watchCollection returned the new data both in the newCollection and the oldCollection arguments of the listener
@@ -439,6 +441,8 @@ function $RootScopeProvider(){ | |||
changeDetected++; | |||
} | |||
|
|||
oldArray = oldValue.length > 0 ? Array.prototype.slice.call(oldValue, 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.
this should be:
if (listener.length > 1) {
oldArray = slice(oldValue, 0);
}
or something along those lines. the important bit is listener.length - we don't want to compute this value if the listener is not asking for it. (we'll break the listener if it uses the arguments
object to get hold of args, but I think it's a fair trade-off for hot code like this.
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.
we also have a slice
fn defined in Angular.js file, so you should use it
Another implementation + related tweaks here: #5661 |
Originally we destroyed the oldValue by incrementaly copying over portions of the newValue into the oldValue during dirty-checking, this resulted in oldValue to be equal to newValue by the time we called the watchCollection listener. The fix creates a copy of the newValue each time a change is detected and then uses that copy *the next time* a change is detected. To make `$watchCollection` behave the same way as `$watch`, during the first iteration the listener is called with newValue and oldValue being identical. Since many of the corner-cases are already covered by existing tests, I refactored the test logging to include oldValue and made the tests more readable. Closes angular#2621 Closes angular#5661 Closes angular#5688
I have an alternative implementation, please take a look: #6736 |
Originally we destroyed the oldValue by incrementaly copying over portions of the newValue into the oldValue during dirty-checking, this resulted in oldValue to be equal to newValue by the time we called the watchCollection listener. The fix creates a copy of the newValue each time a change is detected and then uses that copy *the next time* a change is detected. To make `$watchCollection` behave the same way as `$watch`, during the first iteration the listener is called with newValue and oldValue being identical. Since many of the corner-cases are already covered by existing tests, I refactored the test logging to include oldValue and made the tests more readable. Closes angular#2621 Closes angular#5661 Closes angular#5688 Closes angular#6736
Originally we destroyed the oldValue by incrementaly copying over portions of the newValue into the oldValue during dirty-checking, this resulted in oldValue to be equal to newValue by the time we called the watchCollection listener. The fix creates a copy of the newValue each time a change is detected and then uses that copy *the next time* a change is detected. To make `$watchCollection` behave the same way as `$watch`, during the first iteration the listener is called with newValue and oldValue being identical. Since many of the corner-cases are already covered by existing tests, I refactored the test logging to include oldValue and made the tests more readable. Closes #2621 Closes #5661 Closes #5688 Closes #6736
...former array data
related to #1751
When watching arrays, $watchCollection returned the new data both in the newCollection
and the oldCollection arguments of the listener
Split from PR #3865