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

Commit 4f32e3e

Browse files
fix(ngSwitch): use the correct transclusion scope
If an ngSwitchWhen or ngSwitchDefault directive is on an element that also contains a transclusion directive (such as ngRepeat) the new scope should be the one provided by the bound transclusion function. Previously we were incorrectly creating a simple child of the main ngSwitch scope. BREAKING CHANGE: ** Directive Priority Changed ** - this commit changes the priority of `ngSwitchWhen` and `ngSwitchDefault` from 800 to 1200. This makes their priority higher than `ngRepeat`, which allows items to be repeated on the switch case element reliably. In general your directives should have a lower priority than these directives if you want them to exist inside the case elements. If you relied on the priority of these directives then you should check that your code still operates correctly. Closes #8235
1 parent 81d9193 commit 4f32e3e

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

src/ng/directive/ngSwitch.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,8 @@ var ngSwitchDirective = ['$animate', function($animate) {
166166
if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
167167
scope.$eval(attr.change);
168168
forEach(selectedTranscludes, function(selectedTransclude) {
169-
var selectedScope = scope.$new();
170-
selectedScopes.push(selectedScope);
171-
selectedTransclude.transclude(selectedScope, function(caseElement) {
169+
selectedTransclude.transclude(function(caseElement, selectedScope) {
170+
selectedScopes.push(selectedScope);
172171
var anchor = selectedTransclude.element;
173172

174173
selectedElements.push(caseElement);
@@ -183,7 +182,7 @@ var ngSwitchDirective = ['$animate', function($animate) {
183182

184183
var ngSwitchWhenDirective = ngDirective({
185184
transclude: 'element',
186-
priority: 800,
185+
priority: 1200,
187186
require: '^ngSwitch',
188187
multiElement: true,
189188
link: function(scope, element, attrs, ctrl, $transclude) {
@@ -194,7 +193,7 @@ var ngSwitchWhenDirective = ngDirective({
194193

195194
var ngSwitchDefaultDirective = ngDirective({
196195
transclude: 'element',
197-
priority: 800,
196+
priority: 1200,
198197
require: '^ngSwitch',
199198
multiElement: true,
200199
link: function(scope, element, attr, ctrl, $transclude) {

test/ng/directive/ngSwitchSpec.js

+23-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ describe('ngSwitch', function() {
241241
$rootScope.url = 'x';
242242
$rootScope.$apply();
243243
expect(getChildScope()).toBeUndefined();
244-
expect(child1.$destroy).toHaveBeenCalledOnce();
244+
expect(child1.$destroy).toHaveBeenCalled();
245245

246246
$rootScope.url = 'a';
247247
$rootScope.$apply();
@@ -251,6 +251,28 @@ describe('ngSwitch', function() {
251251
}));
252252

253253

254+
it("should use the correct transclusion scope if there is a transclude directive on the ng-swith-when/ng-switch-default element", inject(function($rootScope, $compile) {
255+
element = $compile(
256+
'<div ng-switch="foo">' +
257+
'<pre ng-switch-when="item1" ng-repeat="bar in bars">' +
258+
'foo = {{foo}}' +
259+
'bar = {{bar}}' +
260+
'$index = {{$index}}' +
261+
'</pre>' +
262+
'</div>'
263+
)($rootScope);
264+
$rootScope.$apply('foo="item1";bars=["one", "two"]');
265+
expect(element.text()).toEqual(
266+
'foo = item1' +
267+
'bar = one' +
268+
'$index = 0' +
269+
'foo = item1' +
270+
'bar = two' +
271+
'$index = 1'
272+
);
273+
}));
274+
275+
254276
it('should not leak jq data when compiled but not attached to parent when parent is destroyed',
255277
inject(function($rootScope, $compile) {
256278
element = $compile(

0 commit comments

Comments
 (0)