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

Commit 2d0f6cc

Browse files
Daniel Tabuencatbosch
Daniel Tabuenca
authored andcommitted
fix($compile): ensure isolated local watches' lastValue is always in sync
When using two-way binding with isolate scope, under some circumstances the lastValue variable captured in the parentValueWatch function can get out of sync. Specifically, if both the value in the origin scope as well as the value in the isolate scope get independently updated to the same value within one digest cycle, the lastValue is never updated. This potentially causes the watch to make the wrong decision as to which side to update on subsequent passes. This fixes things by ensuring lastValue is always set to the last seen value even if the watch's logic was short circuited because there was no difference between the values in the original and isolate scopes. Closes #5182
1 parent 9a81b86 commit 2d0f6cc

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

src/ng/compile.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1438,13 +1438,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
14381438
// we are out of sync and need to copy
14391439
if (parentValue !== lastValue) {
14401440
// parent changed and it has precedence
1441-
lastValue = isolateScope[scopeName] = parentValue;
1441+
isolateScope[scopeName] = parentValue;
14421442
} else {
14431443
// if the parent can be assigned then do so
1444-
parentSet(scope, parentValue = lastValue = isolateScope[scopeName]);
1444+
parentSet(scope, parentValue = isolateScope[scopeName]);
14451445
}
14461446
}
1447-
return parentValue;
1447+
return lastValue = parentValue;
14481448
});
14491449
break;
14501450

test/ng/compileSpec.js

+18
Original file line numberDiff line numberDiff line change
@@ -2386,6 +2386,24 @@ describe('$compile', function() {
23862386
expect(componentScope.refAlias).toBe($rootScope.name);
23872387
}));
23882388

2389+
it('should not break if local and origin both change to the same value', inject(function() {
2390+
$rootScope.name = 'aaa';
2391+
2392+
compile('<div><span my-component ref="name">');
2393+
2394+
//change both sides to the same item withing the same digest cycle
2395+
componentScope.ref = 'same';
2396+
$rootScope.name = 'same';
2397+
$rootScope.$apply();
2398+
2399+
//change origin back to it's previous value
2400+
$rootScope.name = 'aaa';
2401+
$rootScope.$apply();
2402+
2403+
expect($rootScope.name).toBe('aaa');
2404+
expect(componentScope.ref).toBe('aaa');
2405+
}));
2406+
23892407
it('should complain on non assignable changes', inject(function() {
23902408
compile('<div><span my-component ref="\'hello \' + name">');
23912409
$rootScope.name = 'world';

0 commit comments

Comments
 (0)