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

Commit 32aa491

Browse files
committed
fix(ngSwitch): properly support case labels with different numbers of transclude fns
Due to a regression introduced several releases ago, the ability for multiple transclude functions to work correctly changed, as they would break if different case labels had different numbers of transclude functions. This CL corrects this by not assuming that previous elements and scope count have the same length. Fixes 7372 Closes 7373
1 parent 31bdb60 commit 32aa491

File tree

2 files changed

+40
-25
lines changed

2 files changed

+40
-25
lines changed

src/ng/directive/ngSwitch.js

+17-25
Original file line numberDiff line numberDiff line change
@@ -138,37 +138,29 @@ var ngSwitchDirective = ['$animate', function($animate) {
138138
}],
139139
link: function(scope, element, attr, ngSwitchController) {
140140
var watchExpr = attr.ngSwitch || attr.on,
141-
selectedTranscludes,
142-
selectedElements,
143-
previousElements,
141+
selectedTranscludes = [],
142+
selectedElements = [],
143+
previousElements = [],
144144
selectedScopes = [];
145145

146146
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
147-
var i, ii = selectedScopes.length;
148-
if(ii > 0) {
149-
if(previousElements) {
150-
for (i = 0; i < ii; i++) {
151-
previousElements[i].remove();
152-
}
153-
previousElements = null;
154-
}
147+
var i, ii;
148+
for (i = 0, ii = previousElements.length; i < ii; ++i) {
149+
previousElements[i].remove();
150+
}
151+
previousElements.length = 0;
155152

156-
previousElements = [];
157-
for (i= 0; i<ii; i++) {
158-
var selected = selectedElements[i];
159-
selectedScopes[i].$destroy();
160-
previousElements[i] = selected;
161-
$animate.leave(selected, function() {
162-
previousElements.splice(i, 1);
163-
if(previousElements.length === 0) {
164-
previousElements = null;
165-
}
166-
});
167-
}
153+
for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
154+
var selected = selectedElements[i];
155+
selectedScopes[i].$destroy();
156+
previousElements[i] = selected;
157+
$animate.leave(selected, function() {
158+
previousElements.splice(i, 1);
159+
});
168160
}
169161

170-
selectedElements = [];
171-
selectedScopes = [];
162+
selectedElements.length = 0;
163+
selectedScopes.length = 0;
172164

173165
if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
174166
scope.$eval(attr.change);

test/ng/directive/ngSwitchSpec.js

+23
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,29 @@ describe('ngSwitch', function() {
212212
// element now contains only empty repeater. this element is dealocated by local afterEach.
213213
// afterwards a global afterEach will check for leaks in jq data cache object
214214
}));
215+
216+
217+
it('should properly support case labels with different numbers of transclude fns', inject(function($rootScope, $compile) {
218+
element = $compile(
219+
'<div ng-switch="mode">' +
220+
'<p ng-switch-when="a">Block1</p>' +
221+
'<p ng-switch-when="a">Block2</p>' +
222+
'<a href ng-switch-when="b">a</a>' +
223+
'</div>'
224+
)($rootScope);
225+
226+
$rootScope.$apply('mode = "a"');
227+
expect(element.children().length).toBe(2);
228+
229+
$rootScope.$apply('mode = "b"');
230+
expect(element.children().length).toBe(1);
231+
232+
$rootScope.$apply('mode = "a"');
233+
expect(element.children().length).toBe(2);
234+
235+
$rootScope.$apply('mode = "b"');
236+
expect(element.children().length).toBe(1);
237+
}));
215238
});
216239

217240
describe('ngSwitch animations', function() {

0 commit comments

Comments
 (0)