Skip to content

Commit

Permalink
Making watchCollection call the listener before clobbering oldValue
Browse files Browse the repository at this point in the history
I took the naive approach suggested in angular#2621 of separating out the
changeDetected logic from the rest of the watch to give the listener
time to execute before oldCollection is overwritten.  The logic should
be identical to what's in the main repo, except no changes are made to
the closed-over state until after listener is called back.
Unfortunately, this doesn't appear to work, as the watchCollection
tests are now all failing.

I need to learn more about Karma so I can better debug this, and take
more time to grok the logic of the function before I'd have a shot at
fixing it.
  • Loading branch information
appsforartists committed Jun 1, 2013
1 parent 9814c75 commit f417df8
Showing 1 changed file with 40 additions and 14 deletions.
54 changes: 40 additions & 14 deletions src/ng/rootScope.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,32 +365,67 @@ function $RootScopeProvider(){

function $watchCollectionWatch() {
newValue = objGetter(self);

if (!isObject(newValue) && oldValue !== newValue) {
return changeDetected++;
}

if (isArrayLike(newValue)) {
var newLength = newValue.length;

if (oldValue !== internalArray || oldValue.length != newLength) {
return changeDetected++;
}

for (var i = 0; i < newLength; i++) {
if (oldValue[i] !== newValue[i]) {
return changeDetected++;
}
}

} else {
if (oldValue !== internalObject) {
return changeDetected++;
}

for (var key in newValue) {
if (
newValue.hasOwnProperty(key) &&
(!oldValue.hasOwnProperty(key) || oldValue[key] !== newValue[key])
) {
return changeDetected++;
}
}
}
}

function $watchCollectionAction() {
var newLength, key;

newValue = objGetter(self);

listener(newValue, oldValue, self);

if (!isObject(newValue)) {
if (oldValue !== newValue) {
oldValue = newValue;
changeDetected++;
}
} else if (isArrayLike(newValue)) {
if (oldValue !== internalArray) {
// we are transitioning from something which was not an array into array.
oldValue = internalArray;
oldLength = oldValue.length = 0;
changeDetected++;
}

newLength = newValue.length;

if (oldLength !== newLength) {
// if lengths do not match we need to trigger change notification
changeDetected++;
oldValue.length = oldLength = newLength;
}
// copy the items to oldValue and look for changes.
for (var i = 0; i < newLength; i++) {
if (oldValue[i] !== newValue[i]) {
changeDetected++;
oldValue[i] = newValue[i];
}
}
Expand All @@ -399,7 +434,6 @@ function $RootScopeProvider(){
// we are transitioning from something which was not an object into object.
oldValue = internalObject = {};
oldLength = 0;
changeDetected++;
}
// copy the items to oldValue and look for changes.
newLength = 0;
Expand All @@ -408,32 +442,24 @@ function $RootScopeProvider(){
newLength++;
if (oldValue.hasOwnProperty(key)) {
if (oldValue[key] !== newValue[key]) {
changeDetected++;
oldValue[key] = newValue[key];
}
} else {
oldLength++;
oldValue[key] = newValue[key];
changeDetected++;
}
}
}
if (oldLength > newLength) {
// we used to have more keys, need to find them and destroy them.
changeDetected++;
for(key in oldValue) {
for (key in oldValue) {
if (oldValue.hasOwnProperty(key) && !newValue.hasOwnProperty(key)) {
oldLength--;
delete oldValue[key];
}
}
}
}
return changeDetected;
}

function $watchCollectionAction() {
listener(newValue, oldValue, self);
}

return this.$watch($watchCollectionWatch, $watchCollectionAction);
Expand Down

0 comments on commit f417df8

Please sign in to comment.