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

feat(ngSwitch): Allow multiple case matches for one element #3516

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/ng/directive/ngSwitch.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
*
* * `ngSwitchWhen`: the case statement to match against. If match then this
* case will be displayed. If the same match appears multiple times, all the
* elements will be displayed.
* elements will be displayed. You can also use an array, which allows
* specifying multiple values for the same element. Values will be evaluated
* within the scope when using the array notation.
* * `ngSwitchDefault`: the default case when no other case match. If there
* are multiple default cases, all of them will be displayed when no other
* case match.
Expand All @@ -54,7 +56,8 @@
<div class="animate-switch-container"
ng-switch on="selection">
<div ng-switch-when="settings">Settings Div</div>
<div ng-switch-when="home">Home Span</div>
<div ng-switch-when="home">Home Div</div>
<div ng-switch-when="['home', 'settings']">Settings &amp; Home</div>
<div ng-switch-default>default</div>
</div>
</div>
Expand Down Expand Up @@ -163,14 +166,31 @@ var ngSwitchDirective = ['$animate', function($animate) {
}
}];

var SIMPLEARRAY_TEST = /^\s*?\[(.*)\]\s*?$/;

var ngSwitchWhenDirective = ngDirective({
transclude: 'element',
priority: 500,
require: '^ngSwitch',
compile: function(element, attrs, transclude) {
return function(scope, element, attr, ctrl) {
ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: transclude, element: element });
var a = attrs.ngSwitchWhen,
prev = [],
addValue = function(when) {
// avoid multiple matches for the same element
if (!prev[when]) {
ctrl.cases['!' + when] = (ctrl.cases['!' + when] || []);
ctrl.cases['!' + when].push({ transclude: transclude, element: element });
prev[when] = true;
}
}
if (SIMPLEARRAY_TEST.test(a)) {
var whenValue = scope.$eval(a);
forEach(whenValue, addValue);
}
else {
addValue(a);
}
};
}
});
Expand Down
32 changes: 32 additions & 0 deletions test/ng/directive/ngSwitchSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,38 @@ describe('ngSwitch', function() {
}));


it('should allow multiple switch-whens when using array notation', inject(function($rootScope, $compile) {
element = $compile(
'<ul ng-switch="select">' +
'<li ng-switch-when="1">first:{{name}}</li>' +
'<li ng-switch-when="[1,8-6]"> both:{{name}}</li>' +
'<li ng-switch-when="2"> second:{{name}}</li>' +
'<li ng-switch-when="true">true:{{name}}</li>' +
'</ul>')($rootScope);
$rootScope.select = 1;
$rootScope.name="pete";
$rootScope.$apply();
expect(element.text()).toEqual('first:pete both:pete');
$rootScope.select = 2;
$rootScope.$apply();
expect(element.text()).toEqual(' both:pete second:pete');
}));


it('should switch only once even if multiple whens matches the same element when using array notation', inject(function($rootScope, $compile) {
element = $compile(
'<ul ng-switch="select">' +
'<li ng-switch-when="1">first:{{name}}</li>' +
'<li ng-switch-when="[2,8-6]"> both:{{name}}</li>' +
'<li ng-switch-when="2"> second:{{name}}</li>' +
'<li ng-switch-when="true">true:{{name}}</li>' +
'</ul>')($rootScope);
$rootScope.name="pete";
$rootScope.select = 2;
$rootScope.$apply();
expect(element.text()).toEqual(' both:pete second:pete');
}));

it('should switch on switch-when-default', inject(function($rootScope, $compile) {
element = $compile(
'<ng:switch on="select">' +
Expand Down