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

Commit f8c8cf6

Browse files
vojtajinapetebacondarwin
authored andcommitted
fix($rootScope): allow destroying a root scope
When running (i.e. bootstrapping and killing) multiple apps on the same page, it makes sense to destroy the root scope. Closes #11241 Closes #10895
1 parent 9f7a80c commit f8c8cf6

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

src/ng/rootScope.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -871,13 +871,12 @@ function $RootScopeProvider() {
871871
* clean up DOM bindings before an element is removed from the DOM.
872872
*/
873873
$destroy: function() {
874-
// we can't destroy the root scope or a scope that has been already destroyed
874+
// We can't destroy a scope that has been already destroyed.
875875
if (this.$$destroyed) return;
876876
var parent = this.$parent;
877877

878878
this.$broadcast('$destroy');
879879
this.$$destroyed = true;
880-
if (this === $rootScope) return;
881880

882881
incrementWatchersCount(this, -this.$$watchersCount);
883882
for (var eventName in this.$$listenerCount) {
@@ -886,8 +885,8 @@ function $RootScopeProvider() {
886885

887886
// sever all the references to parent scopes (after this cleanup, the current scope should
888887
// not be retained by any of our references and should be eligible for garbage collection)
889-
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
890-
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
888+
if (parent && parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
889+
if (parent && parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
891890
if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
892891
if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;
893892

test/ng/rootScopeSpec.js

+21-4
Original file line numberDiff line numberDiff line change
@@ -1021,16 +1021,33 @@ describe('Scope', function() {
10211021

10221022

10231023
it('should broadcast $destroy on rootScope', inject(function($rootScope) {
1024-
var spy = spyOn(angular, 'noop');
1025-
$rootScope.$on('$destroy', angular.noop);
1024+
var spy = jasmine.createSpy('$destroy handler');
1025+
$rootScope.$on('$destroy', spy);
10261026
$rootScope.$destroy();
1027-
$rootScope.$digest();
1028-
expect(log).toEqual('123');
10291027
expect(spy).toHaveBeenCalled();
10301028
expect($rootScope.$$destroyed).toBe(true);
10311029
}));
10321030

10331031

1032+
it('should remove all listeners after $destroy of rootScope', inject(function($rootScope) {
1033+
var spy = jasmine.createSpy('$destroy handler');
1034+
$rootScope.$on('dummy', spy);
1035+
$rootScope.$destroy();
1036+
$rootScope.$broadcast('dummy');
1037+
expect(spy).not.toHaveBeenCalled();
1038+
}));
1039+
1040+
1041+
it('should remove all watchers after $destroy of rootScope', inject(function($rootScope) {
1042+
var spy = jasmine.createSpy('$watch spy');
1043+
var digest = $rootScope.$digest;
1044+
$rootScope.$watch(spy);
1045+
$rootScope.$destroy();
1046+
digest.call($rootScope);
1047+
expect(spy).not.toHaveBeenCalled();
1048+
}));
1049+
1050+
10341051
it('should remove first', inject(function($rootScope) {
10351052
first.$destroy();
10361053
$rootScope.$digest();

0 commit comments

Comments
 (0)