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

Commit d9448dc

Browse files
fix($compile): still trigger $onChanges even if the inner value already matches the new value
Closes #14406
1 parent e9c718a commit d9448dc

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/ng/compile.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,10 +3210,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
32103210
destination[scopeName] = parentGet(scope);
32113211
initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);
32123212

3213-
removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newParentValue) {
3214-
var oldValue = destination[scopeName];
3215-
recordChanges(scopeName, newParentValue, oldValue);
3216-
destination[scopeName] = newParentValue;
3213+
removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newValue, oldValue) {
3214+
if (newValue === oldValue) {
3215+
// If the new and old values are identical then this is the first time the watch has been triggered
3216+
// So instead we use the current value on the destination as the old value
3217+
oldValue = destination[scopeName];
3218+
}
3219+
recordChanges(scopeName, newValue, oldValue);
3220+
destination[scopeName] = newValue;
32173221
}, parentGet.literal);
32183222

32193223
removeWatchCollection.push(removeWatch);
@@ -3246,7 +3250,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
32463250
onChangesQueue.push(triggerOnChangesHook);
32473251
}
32483252
// If the has been a change on this property already then we need to reuse the previous value
3249-
if (changes[key]) {
3253+
if (isDefined(changes[key])) {
32503254
previousValue = changes[key].previousValue;
32513255
}
32523256
// Store this change

test/ng/compileSpec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,6 +3741,31 @@ describe('$compile', function() {
37413741
});
37423742

37433743

3744+
it('should trigger `$onChanges` even if the inner value already equals the new outer value', function() {
3745+
var log = [];
3746+
function TestController() { }
3747+
TestController.prototype.$onChanges = function(change) { log.push(change); };
3748+
3749+
angular.module('my', [])
3750+
.component('c1', {
3751+
controller: TestController,
3752+
bindings: { 'prop1': '<' }
3753+
});
3754+
3755+
module('my');
3756+
inject(function($compile, $rootScope) {
3757+
element = $compile('<c1 prop1="val"></c1>')($rootScope);
3758+
3759+
$rootScope.$apply('val = 1');
3760+
expect(log.pop()).toEqual({prop1: jasmine.objectContaining({previousValue: undefined, currentValue: 1})});
3761+
3762+
element.isolateScope().$ctrl.prop1 = 2;
3763+
$rootScope.$apply('val = 2');
3764+
expect(log.pop()).toEqual({prop1: jasmine.objectContaining({previousValue: 1, currentValue: 2})});
3765+
});
3766+
});
3767+
3768+
37443769
it('should pass the original value as `previousValue` even if there were multiple changes in a single digest', function() {
37453770
var log = [];
37463771
function TestController() { }

0 commit comments

Comments
 (0)