Skip to content

Commit 0202b1c

Browse files
lgalfasopetebacondarwin
authored andcommitted
feat(ngSwitch): allow multiple case matches via optional attribute ngSwitchWhenSeparator
Adds an optional attribute `ngSwitchWhenSeparator` that allows multiple tokens to match a given `ngSwitchWhen`. Closes angular#3410 Closes angular#3516 Closes angular#10798
1 parent 89fa748 commit 0202b1c

File tree

2 files changed

+122
-3
lines changed

2 files changed

+122
-3
lines changed

src/ng/directive/ngSwitch.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@
5050
*
5151
* * `ngSwitchWhen`: the case statement to match against. If match then this
5252
* case will be displayed. If the same match appears multiple times, all the
53-
* elements will be displayed.
53+
* elements will be displayed. It is possible to associate mutiple values to
54+
* the same `ngSwitchWhen` by defining the optional attribute
55+
* `ngSwitchWhenSeparator`. The separator will be used to split the value of
56+
* the `ngSwitchWhen` attribute into multiple tokens, and the element will show
57+
* if any of the `ngSwitch` evaluates to any of these tokens.
5458
* * `ngSwitchDefault`: the default case when no other case match. If there
5559
* are multiple default cases, all of them will be displayed when no other
5660
* case match.
@@ -189,8 +193,16 @@ var ngSwitchWhenDirective = ngDirective({
189193
require: '^ngSwitch',
190194
multiElement: true,
191195
link: function(scope, element, attrs, ctrl, $transclude) {
192-
ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
193-
ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: $transclude, element: element });
196+
197+
var cases = attrs.ngSwitchWhen.split(attrs.ngSwitchWhenSeparator).sort().filter(
198+
// Filter duplicate cases
199+
function(element, index, array) { return array[index - 1] !== element; }
200+
);
201+
202+
forEach(cases, function(whenCase) {
203+
ctrl.cases['!' + whenCase] = (ctrl.cases['!' + whenCase] || []);
204+
ctrl.cases['!' + whenCase].push({ transclude: $transclude, element: element });
205+
});
194206
}
195207
});
196208

test/ng/directive/ngSwitchSpec.js

+107
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,113 @@ describe('ngSwitch', function() {
299299
$rootScope.$apply('mode = "b"');
300300
expect(element.children().length).toBe(1);
301301
}));
302+
303+
304+
describe('ngSwitchWhen separator', function() {
305+
it('should be possible to define a separator', inject(function($rootScope, $compile) {
306+
element = $compile(
307+
'<div ng-switch="mode">' +
308+
'<p ng-switch-when="a|b" ng-switch-when-separator="|">Block1|</p>' +
309+
'<p ng-switch-when="a">Block2|</p>' +
310+
'<p ng-switch-default>Block3|</div>' +
311+
'</div>'
312+
)($rootScope);
313+
314+
$rootScope.$apply('mode = "a"');
315+
expect(element.children().length).toBe(2);
316+
expect(element.text()).toBe('Block1|Block2|');
317+
$rootScope.$apply('mode = "b"');
318+
expect(element.children().length).toBe(1);
319+
expect(element.text()).toBe('Block1|');
320+
$rootScope.$apply('mode = "c"');
321+
expect(element.children().length).toBe(1);
322+
expect(element.text()).toBe('Block3|');
323+
}));
324+
325+
326+
it('should be possible to use a separator at the end of the value', inject(function($rootScope, $compile) {
327+
element = $compile(
328+
'<div ng-switch="mode">' +
329+
'<p ng-switch-when="a|b|" ng-switch-when-separator="|">Block1|</p>' +
330+
'<p ng-switch-when="a">Block2|</p>' +
331+
'<p ng-switch-default>Block3|</div>' +
332+
'</div>'
333+
)($rootScope);
334+
335+
$rootScope.$apply('mode = "a"');
336+
expect(element.children().length).toBe(2);
337+
expect(element.text()).toBe('Block1|Block2|');
338+
$rootScope.$apply('mode = ""');
339+
expect(element.children().length).toBe(1);
340+
expect(element.text()).toBe('Block1|');
341+
$rootScope.$apply('mode = "c"');
342+
expect(element.children().length).toBe(1);
343+
expect(element.text()).toBe('Block3|');
344+
}));
345+
346+
347+
it('should be possible to use the empty string as a separator', inject(function($rootScope, $compile) {
348+
element = $compile(
349+
'<div ng-switch="mode">' +
350+
'<p ng-switch-when="ab" ng-switch-when-separator="">Block1|</p>' +
351+
'<p ng-switch-when="a">Block2|</p>' +
352+
'<p ng-switch-default>Block3|</div>' +
353+
'</div>'
354+
)($rootScope);
355+
356+
$rootScope.$apply('mode = "a"');
357+
expect(element.children().length).toBe(2);
358+
expect(element.text()).toBe('Block1|Block2|');
359+
$rootScope.$apply('mode = "b"');
360+
expect(element.children().length).toBe(1);
361+
expect(element.text()).toBe('Block1|');
362+
$rootScope.$apply('mode = "c"');
363+
expect(element.children().length).toBe(1);
364+
expect(element.text()).toBe('Block3|');
365+
}));
366+
367+
368+
it('should be possible to use separators that are multiple characters long', inject(function($rootScope, $compile) {
369+
element = $compile(
370+
'<div ng-switch="mode">' +
371+
'<p ng-switch-when="a||b|a" ng-switch-when-separator="||">Block1|</p>' +
372+
'<p ng-switch-when="a">Block2|</p>' +
373+
'<p ng-switch-default>Block3|</div>' +
374+
'</div>'
375+
)($rootScope);
376+
377+
$rootScope.$apply('mode = "a"');
378+
expect(element.children().length).toBe(2);
379+
expect(element.text()).toBe('Block1|Block2|');
380+
$rootScope.$apply('mode = "b|a"');
381+
expect(element.children().length).toBe(1);
382+
expect(element.text()).toBe('Block1|');
383+
$rootScope.$apply('mode = "c"');
384+
expect(element.children().length).toBe(1);
385+
expect(element.text()).toBe('Block3|');
386+
}));
387+
388+
389+
it('should ignore multiple appearances of the same item', inject(function($rootScope, $compile) {
390+
element = $compile(
391+
'<div ng-switch="mode">' +
392+
'<p ng-switch-when="a|b|a" ng-switch-when-separator="|">Block1|</p>' +
393+
'<p ng-switch-when="a">Block2|</p>' +
394+
'<p ng-switch-default>Block3|</div>' +
395+
'</div>'
396+
)($rootScope);
397+
398+
$rootScope.$apply('mode = "a"');
399+
expect(element.children().length).toBe(2);
400+
expect(element.text()).toBe('Block1|Block2|');
401+
$rootScope.$apply('mode = "b"');
402+
expect(element.children().length).toBe(1);
403+
expect(element.text()).toBe('Block1|');
404+
$rootScope.$apply('mode = "c"');
405+
expect(element.children().length).toBe(1);
406+
expect(element.text()).toBe('Block3|');
407+
}));
408+
});
302409
});
303410

304411
describe('ngSwitch animation', function() {

0 commit comments

Comments
 (0)