Skip to content

Commit ecce65a

Browse files
committed
fix(Scope): $broadcast and $emit should set event.currentScope to null
When a event is finished propagating through Scope hierarchy the event's `currentScope` property should be reset to `null` to avoid accidental use of this property in asynchronous event handlers. In the previous code, the event's property would contain a reference to the last Scope instance that was visited during the traversal, which is unlikely what the code trying to grab scope reference expects. BREAKING CHANGE: $broadcast and $emit will now reset the `currentScope` property of the event to null once the event finished propagating. If any code depends on asynchronously accessing thei `currentScope` property, it should be migrated to use `targetScope` instead. All of these cases should be considered programming bugs. Closes angular#7445"
1 parent 6b52848 commit ecce65a

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/ng/rootScope.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1065,11 +1065,16 @@ function $RootScopeProvider(){
10651065
}
10661066
}
10671067
//if any listener on the current scope stops propagation, prevent bubbling
1068-
if (stopPropagation) return event;
1068+
if (stopPropagation) {
1069+
event.currentScope = null;
1070+
return event;
1071+
}
10691072
//traverse upwards
10701073
scope = scope.$parent;
10711074
} while (scope);
10721075

1076+
event.currentScope = null;
1077+
10731078
return event;
10741079
},
10751080

@@ -1142,6 +1147,8 @@ function $RootScopeProvider(){
11421147
}
11431148
}
11441149

1150+
event.currentScope = null;
1151+
11451152
return event;
11461153
}
11471154
};

test/ng/rootScopeSpec.js

+37-3
Original file line numberDiff line numberDiff line change
@@ -1563,15 +1563,30 @@ describe('Scope', function() {
15631563

15641564
describe('event object', function() {
15651565
it('should have methods/properties', function() {
1566-
var event;
1566+
var eventFired = false;
1567+
15671568
child.$on('myEvent', function(e) {
15681569
expect(e.targetScope).toBe(grandChild);
15691570
expect(e.currentScope).toBe(child);
15701571
expect(e.name).toBe('myEvent');
1572+
eventFired = true;
1573+
});
1574+
grandChild.$emit('myEvent');
1575+
expect(eventFired).toBeDefined();
1576+
});
1577+
1578+
1579+
it("should have it's `currentScope` property set to null after emit", function() {
1580+
var event;
1581+
1582+
child.$on('myEvent', function(e) {
15711583
event = e;
15721584
});
15731585
grandChild.$emit('myEvent');
1574-
expect(event).toBeDefined();
1586+
1587+
expect(event.currentScope).toBe(null);
1588+
expect(event.targetScope).toBe(grandChild);
1589+
expect(event.name).toBe('myEvent');
15751590
});
15761591

15771592

@@ -1584,6 +1599,7 @@ describe('Scope', function() {
15841599
});
15851600
event = grandChild.$emit('myEvent');
15861601
expect(event.defaultPrevented).toBe(true);
1602+
expect(event.currentScope).toBe(null);
15871603
});
15881604
});
15891605
});
@@ -1698,6 +1714,24 @@ describe('Scope', function() {
16981714

16991715
describe('listener', function() {
17001716
it('should receive event object', inject(function($rootScope) {
1717+
var scope = $rootScope,
1718+
child = scope.$new(),
1719+
eventFired = false;
1720+
1721+
child.$on('fooEvent', function(event) {
1722+
eventFired = true;
1723+
expect(event.name).toBe('fooEvent');
1724+
expect(event.targetScope).toBe(scope);
1725+
expect(event.currentScope).toBe(child);
1726+
});
1727+
scope.$broadcast('fooEvent');
1728+
1729+
expect(eventFired).toBe(true);
1730+
}));
1731+
1732+
1733+
it("should have the event's `currentScope` property set to null after broadcast",
1734+
inject(function($rootScope) {
17011735
var scope = $rootScope,
17021736
child = scope.$new(),
17031737
event;
@@ -1709,7 +1743,7 @@ describe('Scope', function() {
17091743

17101744
expect(event.name).toBe('fooEvent');
17111745
expect(event.targetScope).toBe(scope);
1712-
expect(event.currentScope).toBe(child);
1746+
expect(event.currentScope).toBe(null);
17131747
}));
17141748

17151749

0 commit comments

Comments
 (0)