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

Commit 38bf8ef

Browse files
committed
feat(ngSwitch): add an optional attribute ngSwitchWhenSeparator
Adds an optional attribute `ngSwitchWhenSeparator` that allows multiple tokens to match a given `ngSwitchWhen`. Closes #3410 Closes #3516
1 parent 2b8baf7 commit 38bf8ef

File tree

2 files changed

+119
-3
lines changed

2 files changed

+119
-3
lines changed

src/ng/directive/ngSwitch.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@
4848
*
4949
* * `ngSwitchWhen`: the case statement to match against. If match then this
5050
* case will be displayed. If the same match appears multiple times, all the
51-
* elements will be displayed.
51+
* elements will be displayed. It is possible to associate mutiple values to
52+
* the same `ngSwitchWhen` by defining the optional attribute
53+
* `ngSwitchWhenSeparator`. The separator will be used to split the value of
54+
* the `ngSwitchWhen` attribute into multiple tokens, and the element will show
55+
* if any of the `ngSwitch` evaluates to any of these tokens.
5256
* * `ngSwitchDefault`: the default case when no other case match. If there
5357
* are multiple default cases, all of them will be displayed when no other
5458
* case match.
@@ -189,8 +193,13 @@ 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+
var cases = attrs.ngSwitchWhen.split(attrs.ngSwitchWhenSeparator).sort().filter(
197+
function(el, ix, ar) { return ar[ix - 1] !== el;}
198+
);
199+
forEach(cases, function(whenCase) {
200+
ctrl.cases['!' + whenCase] = (ctrl.cases['!' + whenCase] || []);
201+
ctrl.cases['!' + whenCase].push({ transclude: $transclude, element: element });
202+
});
194203
}
195204
});
196205

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)