From 7df8959c56a76daac939d666dac6ea9c8650b95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Galfas=C3=B3?= Date: Wed, 6 Feb 2013 10:08:40 -0300 Subject: [PATCH 1/4] feat(directive): ng:switch Added the ability to handle multiple matches on ng:switch-when and ng:switch-default Closes #1074 --- src/ng/directive/ngSwitch.js | 34 ++++++++++++++++---------- test/ng/directive/ngSwitchSpec.js | 40 +++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/ng/directive/ngSwitch.js b/src/ng/directive/ngSwitch.js index 24c6047ac809..394d57193ac4 100644 --- a/src/ng/directive/ngSwitch.js +++ b/src/ng/directive/ngSwitch.js @@ -68,22 +68,28 @@ var ngSwitchDirective = valueFn({ }, link: function(scope, element, attr, ctrl) { var watchExpr = attr.ngSwitch || attr.on, - selectedTransclude, - selectedElement, - selectedScope; + selectedTranscludes, + selectedElements, + selectedScopes; scope.$watch(watchExpr, function ngSwitchWatchAction(value) { - if (selectedElement) { + angular.forEach(selectedScopes, function(selectedScope) { selectedScope.$destroy(); + }); + angular.forEach(selectedElements, function(selectedElement) { selectedElement.remove(); - selectedElement = selectedScope = null; - } - if ((selectedTransclude = ctrl.cases['!' + value] || ctrl.cases['?'])) { + }); + selectedElements = []; + selectedScopes = []; + if ((selectedTranscludes = ctrl.cases['!' + value] || ctrl.cases['?'])) { scope.$eval(attr.change); - selectedScope = scope.$new(); - selectedTransclude(selectedScope, function(caseElement) { - selectedElement = caseElement; - element.append(caseElement); + angular.forEach(selectedTranscludes, function(selectedTransclude) { + var selectedScope = scope.$new(); + selectedScopes.push(selectedScope); + selectedTransclude(selectedScope, function(caseElement) { + selectedElements.push(caseElement); + element.append(caseElement); + }); }); } }); @@ -96,7 +102,8 @@ var ngSwitchWhenDirective = ngDirective({ require: '^ngSwitch', compile: function(element, attrs, transclude) { return function(scope, element, attr, ctrl) { - ctrl.cases['!' + attrs.ngSwitchWhen] = transclude; + ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []); + ctrl.cases['!' + attrs.ngSwitchWhen].push(transclude); }; } }); @@ -107,7 +114,8 @@ var ngSwitchDefaultDirective = ngDirective({ require: '^ngSwitch', compile: function(element, attrs, transclude) { return function(scope, element, attr, ctrl) { - ctrl.cases['?'] = transclude; + ctrl.cases['?'] = (ctrl.cases['?'] || []); + ctrl.cases['?'].push(transclude); }; } }); diff --git a/test/ng/directive/ngSwitchSpec.js b/test/ng/directive/ngSwitchSpec.js index ee91f79d8667..e3ec107d51d7 100644 --- a/test/ng/directive/ngSwitchSpec.js +++ b/test/ng/directive/ngSwitchSpec.js @@ -35,6 +35,32 @@ describe('ngSwitch', function() { expect(element.text()).toEqual('true:misko'); })); + it('should switch show all the options that match the switch-when', inject(function($rootScope, $compile) { + element = $compile( + '
' + + '
first:{{name}}
' + + '
, first too:{{name}}
' + + '
second:{{name}}
' + + '
true:{{name}}
' + + '
')($rootScope); + expect(element.html()).toEqual( + ''); + $rootScope.select = 1; + $rootScope.$apply(); + expect(element.text()).toEqual('first:, first too:'); + $rootScope.name="shyam"; + $rootScope.$apply(); + expect(element.text()).toEqual('first:shyam, first too:shyam'); + $rootScope.select = 2; + $rootScope.$apply(); + expect(element.text()).toEqual('second:shyam'); + $rootScope.name = 'misko'; + $rootScope.$apply(); + expect(element.text()).toEqual('second:misko'); + $rootScope.select = true; + $rootScope.$apply(); + expect(element.text()).toEqual('true:misko'); + })); it('should switch on switch-when-default', inject(function($rootScope, $compile) { element = $compile( @@ -49,6 +75,20 @@ describe('ngSwitch', function() { expect(element.text()).toEqual('one'); })); + it('should show all switch-when-default', inject(function($rootScope, $compile) { + element = $compile( + '' + + '
one
' + + '
other
' + + '
, other too
' + + '
')($rootScope); + $rootScope.$apply(); + expect(element.text()).toEqual('other, other too'); + $rootScope.select = 1; + $rootScope.$apply(); + expect(element.text()).toEqual('one'); + })); + it('should call change on switch', inject(function($rootScope, $compile) { element = $compile( From 764cc24d9b3605da934ae335d0823aebf3cba2ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Galfas=C3=B3?= Date: Thu, 7 Feb 2013 10:21:12 -0300 Subject: [PATCH 2/4] test(ng:switch) : make the test explicit on the usefulness of the feature make the test explicit that this feature is needed when it is not possible to add some artificial
element --- test/ng/directive/ngSwitchSpec.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/ng/directive/ngSwitchSpec.js b/test/ng/directive/ngSwitchSpec.js index e3ec107d51d7..4f5dc4647c2e 100644 --- a/test/ng/directive/ngSwitchSpec.js +++ b/test/ng/directive/ngSwitchSpec.js @@ -37,12 +37,12 @@ describe('ngSwitch', function() { it('should switch show all the options that match the switch-when', inject(function($rootScope, $compile) { element = $compile( - '
' + - '
first:{{name}}
' + - '
, first too:{{name}}
' + - '
second:{{name}}
' + - '
true:{{name}}
' + - '
')($rootScope); + '
    ' + + '
  • first:{{name}}
  • ' + + '
  • , first too:{{name}}
  • ' + + '
  • second:{{name}}
  • ' + + '
  • true:{{name}}
  • ' + + '
')($rootScope); expect(element.html()).toEqual( ''); $rootScope.select = 1; @@ -77,11 +77,11 @@ describe('ngSwitch', function() { it('should show all switch-when-default', inject(function($rootScope, $compile) { element = $compile( - '' + - '
one
' + - '
other
' + - '
, other too
' + - '
')($rootScope); + '
    ' + + '
  • one
  • ' + + '
  • other
  • ' + + '
  • , other too
  • ' + + '
')($rootScope); $rootScope.$apply(); expect(element.text()).toEqual('other, other too'); $rootScope.select = 1; From fdadd4ed383dcddf8d996bd94b21401b24d18419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Galfas=C3=B3?= Date: Thu, 7 Feb 2013 10:25:18 -0300 Subject: [PATCH 3/4] style(ng:switch): remove unnecessary reference to the angular object --- src/ng/directive/ngSwitch.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ng/directive/ngSwitch.js b/src/ng/directive/ngSwitch.js index 394d57193ac4..4b0bbe023f52 100644 --- a/src/ng/directive/ngSwitch.js +++ b/src/ng/directive/ngSwitch.js @@ -73,17 +73,17 @@ var ngSwitchDirective = valueFn({ selectedScopes; scope.$watch(watchExpr, function ngSwitchWatchAction(value) { - angular.forEach(selectedScopes, function(selectedScope) { + forEach(selectedScopes, function(selectedScope) { selectedScope.$destroy(); }); - angular.forEach(selectedElements, function(selectedElement) { + forEach(selectedElements, function(selectedElement) { selectedElement.remove(); }); selectedElements = []; selectedScopes = []; if ((selectedTranscludes = ctrl.cases['!' + value] || ctrl.cases['?'])) { scope.$eval(attr.change); - angular.forEach(selectedTranscludes, function(selectedTransclude) { + forEach(selectedTranscludes, function(selectedTransclude) { var selectedScope = scope.$new(); selectedScopes.push(selectedScope); selectedTransclude(selectedScope, function(caseElement) { From 7ff5cc75e1a50ffe63da3b95b850abb7ab891316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Galfas=C3=B3?= Date: Thu, 7 Feb 2013 10:27:19 -0300 Subject: [PATCH 4/4] doc(ng:switch): update the documentation on the new feature update the documentation on supporting multiple matches for ng:switch --- src/ng/directive/ngSwitch.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ng/directive/ngSwitch.js b/src/ng/directive/ngSwitch.js index 4b0bbe023f52..69e875e1c019 100644 --- a/src/ng/directive/ngSwitch.js +++ b/src/ng/directive/ngSwitch.js @@ -20,8 +20,11 @@ * On child elments add: * * * `ngSwitchWhen`: the case statement to match against. If match then this - * case will be displayed. - * * `ngSwitchDefault`: the default case when no other casses match. + * case will be displayed. If the same match appears multiple times, all the + * elements will be displayed. + * * `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. * * @example