Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

fix(rootScope): $watchCollection returns in oldCollection a copy of the ... #5688

Conversation

gonzaloruizdevilla
Copy link
Contributor

...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

…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) : [];
Copy link
Contributor

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.

Copy link
Contributor

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

@Narretz
Copy link
Contributor

Narretz commented Jan 17, 2014

Another implementation + related tweaks here: #5661
Would be nice if this makes it to 1.2.10

@ghost ghost assigned vojtajina Jan 22, 2014
@tbosch tbosch modified the milestones: 1.2.12, 1.2.11, 1.2.13 Feb 3, 2014
@btford btford modified the milestones: 1.2.14, 1.2.13 Feb 15, 2014
@IgorMinar IgorMinar modified the milestones: 1.3.0-beta.1, 1.2.14 Mar 1, 2014
@btford btford modified the milestones: 1.3.0-beta.2, 1.3.0-beta.1 Mar 10, 2014
@tbosch tbosch modified the milestones: 1.3.0-beta.3, 1.3.0-beta.2 Mar 14, 2014
IgorMinar added a commit to IgorMinar/angular.js that referenced this pull request Mar 18, 2014
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
@IgorMinar
Copy link
Contributor

I have an alternative implementation, please take a look: #6736

IgorMinar added a commit to IgorMinar/angular.js that referenced this pull request Mar 18, 2014
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
@IgorMinar IgorMinar closed this in 78057a9 Mar 18, 2014
IgorMinar added a commit that referenced this pull request Mar 18, 2014
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
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants