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

Commit 0af1720

Browse files
lgalfasoIgorMinar
authored andcommitted
feat(ngSwitch): support multiple matches on ngSwitchWhen and ngSwitchDefault
Closes #1074
1 parent e19b04c commit 0af1720

File tree

2 files changed

+72
-16
lines changed

2 files changed

+72
-16
lines changed

src/ng/directive/ngSwitch.js

+27-16
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
* On child elments add:
2121
*
2222
* * `ngSwitchWhen`: the case statement to match against. If match then this
23-
* case will be displayed.
24-
* * `ngSwitchDefault`: the default case when no other casses match.
23+
* case will be displayed. If the same match appears multiple times, all the
24+
* elements will be displayed.
25+
* * `ngSwitchDefault`: the default case when no other case match. If there
26+
* are multiple default cases, all of them will be displayed when no other
27+
* case match.
2528
*
2629
* @example
2730
<doc:example>
@@ -69,22 +72,28 @@ var ngSwitchDirective = valueFn({
6972
}],
7073
link: function(scope, element, attr, ctrl) {
7174
var watchExpr = attr.ngSwitch || attr.on,
72-
selectedTransclude,
73-
selectedElement,
74-
selectedScope;
75+
selectedTranscludes,
76+
selectedElements,
77+
selectedScopes = [];
7578

7679
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
77-
if (selectedElement) {
78-
selectedScope.$destroy();
79-
selectedElement.remove();
80-
selectedElement = selectedScope = null;
80+
for (var i= 0, ii=selectedScopes.length; i<ii; i++) {
81+
selectedScopes[i].$destroy();
82+
selectedElements[i].remove();
8183
}
82-
if ((selectedTransclude = ctrl.cases['!' + value] || ctrl.cases['?'])) {
84+
85+
selectedElements = [];
86+
selectedScopes = [];
87+
88+
if ((selectedTranscludes = ctrl.cases['!' + value] || ctrl.cases['?'])) {
8389
scope.$eval(attr.change);
84-
selectedScope = scope.$new();
85-
selectedTransclude(selectedScope, function(caseElement) {
86-
selectedElement = caseElement;
87-
element.append(caseElement);
90+
forEach(selectedTranscludes, function(selectedTransclude) {
91+
var selectedScope = scope.$new();
92+
selectedScopes.push(selectedScope);
93+
selectedTransclude(selectedScope, function(caseElement) {
94+
selectedElements.push(caseElement);
95+
element.append(caseElement);
96+
});
8897
});
8998
}
9099
});
@@ -97,7 +106,8 @@ var ngSwitchWhenDirective = ngDirective({
97106
require: '^ngSwitch',
98107
compile: function(element, attrs, transclude) {
99108
return function(scope, element, attr, ctrl) {
100-
ctrl.cases['!' + attrs.ngSwitchWhen] = transclude;
109+
ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
110+
ctrl.cases['!' + attrs.ngSwitchWhen].push(transclude);
101111
};
102112
}
103113
});
@@ -108,7 +118,8 @@ var ngSwitchDefaultDirective = ngDirective({
108118
require: '^ngSwitch',
109119
compile: function(element, attrs, transclude) {
110120
return function(scope, element, attr, ctrl) {
111-
ctrl.cases['?'] = transclude;
121+
ctrl.cases['?'] = (ctrl.cases['?'] || []);
122+
ctrl.cases['?'].push(transclude);
112123
};
113124
}
114125
});

test/ng/directive/ngSwitchSpec.js

+45
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,36 @@ describe('ngSwitch', function() {
3636
}));
3737

3838

39+
it('should show all switch-whens that match the current value', inject(function($rootScope, $compile) {
40+
element = $compile(
41+
'<ul ng-switch="select">' +
42+
'<li ng-switch-when="1">first:{{name}}</li>' +
43+
'<li ng-switch-when="1">, first too:{{name}}</li>' +
44+
'<li ng-switch-when="2">second:{{name}}</li>' +
45+
'<li ng-switch-when="true">true:{{name}}</li>' +
46+
'</ul>')($rootScope);
47+
expect(element.html()).toEqual('<!-- ngSwitchWhen: 1 -->' +
48+
'<!-- ngSwitchWhen: 1 -->' +
49+
'<!-- ngSwitchWhen: 2 -->' +
50+
'<!-- ngSwitchWhen: true -->');
51+
$rootScope.select = 1;
52+
$rootScope.$apply();
53+
expect(element.text()).toEqual('first:, first too:');
54+
$rootScope.name="shyam";
55+
$rootScope.$apply();
56+
expect(element.text()).toEqual('first:shyam, first too:shyam');
57+
$rootScope.select = 2;
58+
$rootScope.$apply();
59+
expect(element.text()).toEqual('second:shyam');
60+
$rootScope.name = 'misko';
61+
$rootScope.$apply();
62+
expect(element.text()).toEqual('second:misko');
63+
$rootScope.select = true;
64+
$rootScope.$apply();
65+
expect(element.text()).toEqual('true:misko');
66+
}));
67+
68+
3969
it('should switch on switch-when-default', inject(function($rootScope, $compile) {
4070
element = $compile(
4171
'<ng:switch on="select">' +
@@ -50,6 +80,21 @@ describe('ngSwitch', function() {
5080
}));
5181

5282

83+
it('should show all switch-when-default', inject(function($rootScope, $compile) {
84+
element = $compile(
85+
'<ul ng-switch="select">' +
86+
'<li ng-switch-when="1">one</li>' +
87+
'<li ng-switch-default>other</li>' +
88+
'<li ng-switch-default>, other too</li>' +
89+
'</ul>')($rootScope);
90+
$rootScope.$apply();
91+
expect(element.text()).toEqual('other, other too');
92+
$rootScope.select = 1;
93+
$rootScope.$apply();
94+
expect(element.text()).toEqual('one');
95+
}));
96+
97+
5398
it('should call change on switch', inject(function($rootScope, $compile) {
5499
element = $compile(
55100
'<ng:switch on="url" change="name=\'works\'">' +

0 commit comments

Comments
 (0)