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
This commit is contained in:
@@ -138,37 +138,29 @@ var ngSwitchDirective = ['$animate', function($animate) {
|
||||
}],
|
||||
link: function(scope, element, attr, ngSwitchController) {
|
||||
var watchExpr = attr.ngSwitch || attr.on,
|
||||
selectedTranscludes,
|
||||
selectedElements,
|
||||
previousElements,
|
||||
selectedTranscludes = [],
|
||||
selectedElements = [],
|
||||
previousElements = [],
|
||||
selectedScopes = [];
|
||||
|
||||
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
|
||||
var i, ii = selectedScopes.length;
|
||||
if(ii > 0) {
|
||||
if(previousElements) {
|
||||
for (i = 0; i < ii; i++) {
|
||||
previousElements[i].remove();
|
||||
}
|
||||
previousElements = null;
|
||||
}
|
||||
var i, ii;
|
||||
for (i = 0, ii = previousElements.length; i < ii; ++i) {
|
||||
previousElements[i].remove();
|
||||
}
|
||||
previousElements.length = 0;
|
||||
|
||||
previousElements = [];
|
||||
for (i= 0; i<ii; i++) {
|
||||
var selected = selectedElements[i];
|
||||
selectedScopes[i].$destroy();
|
||||
previousElements[i] = selected;
|
||||
$animate.leave(selected, function() {
|
||||
previousElements.splice(i, 1);
|
||||
if(previousElements.length === 0) {
|
||||
previousElements = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
|
||||
var selected = selectedElements[i];
|
||||
selectedScopes[i].$destroy();
|
||||
previousElements[i] = selected;
|
||||
$animate.leave(selected, function() {
|
||||
previousElements.splice(i, 1);
|
||||
});
|
||||
}
|
||||
|
||||
selectedElements = [];
|
||||
selectedScopes = [];
|
||||
selectedElements.length = 0;
|
||||
selectedScopes.length = 0;
|
||||
|
||||
if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
|
||||
scope.$eval(attr.change);
|
||||
|
||||
@@ -212,6 +212,29 @@ describe('ngSwitch', function() {
|
||||
// element now contains only empty repeater. this element is dealocated by local afterEach.
|
||||
// afterwards a global afterEach will check for leaks in jq data cache object
|
||||
}));
|
||||
|
||||
|
||||
it('should properly support case labels with different numbers of transclude fns', inject(function($rootScope, $compile) {
|
||||
element = $compile(
|
||||
'<div ng-switch="mode">' +
|
||||
'<p ng-switch-when="a">Block1</p>' +
|
||||
'<p ng-switch-when="a">Block2</p>' +
|
||||
'<a href ng-switch-when="b">a</a>' +
|
||||
'</div>'
|
||||
)($rootScope);
|
||||
|
||||
$rootScope.$apply('mode = "a"');
|
||||
expect(element.children().length).toBe(2);
|
||||
|
||||
$rootScope.$apply('mode = "b"');
|
||||
expect(element.children().length).toBe(1);
|
||||
|
||||
$rootScope.$apply('mode = "a"');
|
||||
expect(element.children().length).toBe(2);
|
||||
|
||||
$rootScope.$apply('mode = "b"');
|
||||
expect(element.children().length).toBe(1);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('ngSwitch animations', function() {
|
||||
|
||||
Reference in New Issue
Block a user