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

Commit

Permalink
feat(ng:switch): Preserve the order of the elements not in the ng-switch
Browse files Browse the repository at this point in the history
Preserve the order of the elements that are not part of a case nor default in
a ng-switch directive

BREAKING CHANGE: elements not in the ng-switch were rendered after the
    ng-switch elements.  Now they are rendered in-place.

    Ng-switch directives should be updated with non ng-switch elements
    in render-order.  e.g.

    The following was previously rendered with <li>1</li> after "2":

    <ul ng-switch="select">
        <li>1</li>
        <li ng-switch-when="option">2</li>
    </ul>

    To keep the old behaviour, say:

    <ul ng-switch="select">
        <li ng-switch-when="1">2</li>
        <li>1</li>
    </ul>

Closes #1074
  • Loading branch information
lgalfaso authored and jbdeboer committed Mar 11, 2013
1 parent 90ba9aa commit e88d617
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
14 changes: 9 additions & 5 deletions src/ng/directive/ngSwitch.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
* @restrict EA
*
* @description
* Conditionally change the DOM structure.
* Conditionally change the DOM structure. Elements within ngSwitch but without
* ngSwitchWhen or ngSwitchDefault directives will be preserved at the location
* as specified in the template
*
* @usageContent
* <ANY ng-switch-when="matchValue1">...</ANY>
* <ANY ng-switch-when="matchValue2">...</ANY>
* ...
* <ANY ng-switch-default>...</ANY>
* <ANY>...</ANY>
*
* @scope
* @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
Expand All @@ -26,6 +29,7 @@
* are multiple default cases, all of them will be displayed when no other
* case match.
*
*
* @example
<doc:example>
<doc:source>
Expand Down Expand Up @@ -90,9 +94,9 @@ var ngSwitchDirective = valueFn({
forEach(selectedTranscludes, function(selectedTransclude) {
var selectedScope = scope.$new();
selectedScopes.push(selectedScope);
selectedTransclude(selectedScope, function(caseElement) {
selectedTransclude.transclude(selectedScope, function(caseElement) {
selectedElements.push(caseElement);
element.append(caseElement);
selectedTransclude.element.after(caseElement);
});
});
}
Expand All @@ -107,7 +111,7 @@ var ngSwitchWhenDirective = ngDirective({
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);
ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: transclude, element: element });
};
}
});
Expand All @@ -119,7 +123,7 @@ var ngSwitchDefaultDirective = ngDirective({
compile: function(element, attrs, transclude) {
return function(scope, element, attr, ctrl) {
ctrl.cases['?'] = (ctrl.cases['?'] || []);
ctrl.cases['?'].push(transclude);
ctrl.cases['?'].push({ transclude: transclude, element: element });
};
}
});
62 changes: 62 additions & 0 deletions test/ng/directive/ngSwitchSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,68 @@ describe('ngSwitch', function() {
}));


it('should always display the elements that do not match a switch',
inject(function($rootScope, $compile) {
element = $compile(
'<ul ng-switch="select">' +
'<li>always </li>' +
'<li ng-switch-when="1">one </li>' +
'<li ng-switch-when="2">two </li>' +
'<li ng-switch-default>other, </li>' +
'<li ng-switch-default>other too </li>' +
'</ul>')($rootScope);
$rootScope.$apply();
expect(element.text()).toEqual('always other, other too ');
$rootScope.select = 1;
$rootScope.$apply();
expect(element.text()).toEqual('always one ');
}));


it('should display the elements that do not have ngSwitchWhen nor ' +
'ngSwitchDefault at the position specified in the template, when the ' +
'first and last elements in the ngSwitch body do not have a ngSwitch* ' +
'directive', inject(function($rootScope, $compile) {
element = $compile(
'<ul ng-switch="select">' +
'<li>1</li>' +
'<li ng-switch-when="1">2</li>' +
'<li>3</li>' +
'<li ng-switch-when="2">4</li>' +
'<li ng-switch-default>5</li>' +
'<li>6</li>' +
'<li ng-switch-default>7</li>' +
'<li>8</li>' +
'</ul>')($rootScope);
$rootScope.$apply();
expect(element.text()).toEqual('135678');
$rootScope.select = 1;
$rootScope.$apply();
expect(element.text()).toEqual('12368');
}));


it('should display the elements that do not have ngSwitchWhen nor ' +
'ngSwitchDefault at the position specified in the template when the ' +
'first and last elements in the ngSwitch have a ngSwitch* directive',
inject(function($rootScope, $compile) {
element = $compile(
'<ul ng-switch="select">' +
'<li ng-switch-when="1">2</li>' +
'<li>3</li>' +
'<li ng-switch-when="2">4</li>' +
'<li ng-switch-default>5</li>' +
'<li>6</li>' +
'<li ng-switch-default>7</li>' +
'</ul>')($rootScope);
$rootScope.$apply();
expect(element.text()).toEqual('3567');
$rootScope.select = 1;
$rootScope.$apply();
expect(element.text()).toEqual('236');
}));


it('should call change on switch', inject(function($rootScope, $compile) {
element = $compile(
'<ng:switch on="url" change="name=\'works\'">' +
Expand Down

1 comment on commit e88d617

@joelbitar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet!

Please sign in to comment.