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

Commit 29c5530

Browse files
jonathantyatesgkalpak
authored andcommitted
fix($compile): clean up @-binding observers when re-assigning bindings
Fixes #15268 Closes #15298
1 parent 31d55a8 commit 29c5530

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

src/ng/compile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3401,7 +3401,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
34013401
if (!optional && !hasOwnProperty.call(attrs, attrName)) {
34023402
destination[scopeName] = attrs[attrName] = undefined;
34033403
}
3404-
attrs.$observe(attrName, function(value) {
3404+
removeWatch = attrs.$observe(attrName, function(value) {
34053405
if (isString(value) || isBoolean(value)) {
34063406
var oldValue = destination[scopeName];
34073407
recordChanges(scopeName, value, oldValue);
@@ -3420,6 +3420,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
34203420
destination[scopeName] = lastValue;
34213421
}
34223422
initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);
3423+
removeWatchCollection.push(removeWatch);
34233424
break;
34243425

34253426
case '=':

test/ng/compileSpec.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4336,6 +4336,37 @@ describe('$compile', function() {
43364336
});
43374337
});
43384338

4339+
it('should clean up `@`-binding observers when re-assigning bindings', function() {
4340+
var constructorSpy = jasmine.createSpy('constructor');
4341+
var prototypeSpy = jasmine.createSpy('prototype');
4342+
4343+
function TestController() {
4344+
return {$onChanges: constructorSpy};
4345+
}
4346+
TestController.prototype.$onChanges = prototypeSpy;
4347+
4348+
module(function($compileProvider) {
4349+
$compileProvider.component('test', {
4350+
bindings: {attr: '@'},
4351+
controller: TestController
4352+
});
4353+
});
4354+
4355+
inject(function($compile, $rootScope) {
4356+
var template = '<test attr="{{a}}"></test>';
4357+
$rootScope.a = 'foo';
4358+
4359+
element = $compile(template)($rootScope);
4360+
$rootScope.$digest();
4361+
expect(constructorSpy).toHaveBeenCalled();
4362+
expect(prototypeSpy).not.toHaveBeenCalled();
4363+
4364+
constructorSpy.calls.reset();
4365+
$rootScope.$apply('a = "bar"');
4366+
expect(constructorSpy).toHaveBeenCalled();
4367+
expect(prototypeSpy).not.toHaveBeenCalled();
4368+
});
4369+
});
43394370

43404371
it('should not call `$onChanges` twice even when the initial value is `NaN`', function() {
43414372
var onChangesSpy = jasmine.createSpy('$onChanges');

0 commit comments

Comments
 (0)