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

Commit cd2cfaf

Browse files
lgalfasopetebacondarwin
authored andcommitted
refactor($scope): prevent multiple calls to listener on $destroy
Prevent isolated scopes from having listeners that get called multiple times when on `$destroy`
1 parent 86d33c5 commit cd2cfaf

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

src/ng/rootScope.js

+8
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,15 @@ function $RootScopeProvider(){
222222
} else {
223223
parent.$$childHead = parent.$$childTail = child;
224224
}
225+
226+
// The listener needs to be added after the parent is set
227+
if (isolate || parent != this) child.$on('$destroy', destroyChild);
228+
225229
return child;
230+
231+
function destroyChild() {
232+
child.$$destroyed = true;
233+
}
226234
},
227235

228236
/**

test/ng/compileSpec.js

+27-10
Original file line numberDiff line numberDiff line change
@@ -4971,17 +4971,17 @@ describe('$compile', function() {
49714971
return [$rootScope].concat(
49724972
getChildScopes($rootScope)
49734973
).length;
4974+
}
49744975

4975-
function getChildScopes(scope) {
4976-
var children = [];
4977-
if (!scope.$$childHead) { return children; }
4978-
var childScope = scope.$$childHead;
4979-
do {
4980-
children.push(childScope);
4981-
children = children.concat(getChildScopes(childScope));
4982-
} while ((childScope = childScope.$$nextSibling));
4983-
return children;
4984-
}
4976+
function getChildScopes(scope) {
4977+
var children = [];
4978+
if (!scope.$$childHead) { return children; }
4979+
var childScope = scope.$$childHead;
4980+
do {
4981+
children.push(childScope);
4982+
children = children.concat(getChildScopes(childScope));
4983+
} while ((childScope = childScope.$$nextSibling));
4984+
return children;
49854985
}
49864986

49874987
beforeEach(module(function() {
@@ -5117,6 +5117,23 @@ describe('$compile', function() {
51175117
expect(countScopes($rootScope)).toEqual(1);
51185118
}));
51195119

5120+
it('should destroy mark as destroyed all sub scopes of the scope being destroyed',
5121+
inject(function($compile, $rootScope) {
5122+
5123+
element = $compile(
5124+
'<div toggle>' +
5125+
'<div ng:repeat="msg in [\'msg-1\']">{{ msg }}</div>' +
5126+
'</div>'
5127+
)($rootScope);
5128+
5129+
$rootScope.$apply('t = true');
5130+
var childScopes = getChildScopes($rootScope);
5131+
5132+
$rootScope.$apply('t = false');
5133+
for (var i = 0; i < childScopes.length; ++i) {
5134+
expect(childScopes[i].$$destroyed).toBe(true);
5135+
}
5136+
}));
51205137
});
51215138

51225139

test/ng/rootScopeSpec.js

+7
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,13 @@ describe('Scope', function() {
10201020
expect(log).toBe('123');
10211021
}));
10221022

1023+
it('should broadcast the $destroy only once', inject(function($rootScope, log) {
1024+
var isolateScope = first.$new(true);
1025+
isolateScope.$on('$destroy', log.fn('event'));
1026+
first.$destroy();
1027+
isolateScope.$destroy();
1028+
expect(log).toEqual('event');
1029+
}));
10231030

10241031
it('should decrement ancestor $$listenerCount entries', inject(function($rootScope) {
10251032
var EVENT = 'fooEvent',

0 commit comments

Comments
 (0)