1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
'use strict';
/**
* @ngdoc directive
* @name ng.directive:ngSwitch
* @restrict EA
*
* @description
* The ngSwitch directive is used to conditionally swap DOM structure on your template based on a scope expression.
* Elements within ngSwitch but without ngSwitchWhen or ngSwitchDefault directives will be preserved at the location
* as specified in the template.
*
* The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it
* from the template cache), ngSwitch simply choses one of the nested elements and makes it visible based on which element
* matches the value obtained from the evaluated expression. In other words, you define a container element
* (where you place the directive), place an expression on the **on="..." attribute**
* (or the **ng-switch="..." attribute**), define any inner elements inside of the directive and place
* a when attribute per element. The when attribute is used to inform ngSwitch which element to display when the on
* expression is evaluated. If a matching expression is not found via a when attribute then an element with the default
* attribute is displayed.
*
* Additionally, you can also provide animations via the ngAnimate attribute to animate the **enter**
* and **leave** effects.
*
* @animations
* enter - happens after the ngSwtich contents change and the matched child element is placed inside the container
* leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM
*
* @usage
* <ANY ng-switch="expression">
* <ANY ng-switch-when="matchValue1">...</ANY>
* <ANY ng-switch-when="matchValue2">...</ANY>
* <ANY ng-switch-default>...</ANY>
* </ANY>
*
* @scope
* @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
* @paramDescription
* On child elements add:
*
* * `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.
* * `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
<doc:example>
<doc:source>
<script>
function Ctrl($scope) {
$scope.items = ['settings', 'home', 'other'];
$scope.selection = $scope.items[0];
}
</script>
<div ng-controller="Ctrl">
<select ng-model="selection" ng-options="item for item in items">
</select>
<tt>selection={{selection}}</tt>
<hr/>
<div ng-switch on="selection" >
<div ng-switch-when="settings">Settings Div</div>
<span ng-switch-when="home">Home Span</span>
<span ng-switch-default>default</span>
</div>
</div>
</doc:source>
<doc:scenario>
it('should start in settings', function() {
expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Settings Div/);
});
it('should change to home', function() {
select('selection').option('home');
expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Home Span/);
});
it('should select default', function() {
select('selection').option('other');
expect(element('.doc-example-live [ng-switch]').text()).toMatch(/default/);
});
</doc:scenario>
</doc:example>
*/
var ngSwitchDirective = ['$animator', function($animator) {
return {
restrict: 'EA',
require: 'ngSwitch',
// asks for $scope to fool the BC controller module
controller: ['$scope', function ngSwitchController() {
this.cases = {};
}],
link: function(scope, element, attr, ngSwitchController) {
var animate = $animator(scope, attr);
var watchExpr = attr.ngSwitch || attr.on,
selectedTranscludes,
selectedElements,
selectedScopes = [];
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
for (var i= 0, ii=selectedScopes.length; i<ii; i++) {
selectedScopes[i].$destroy();
animate.leave(selectedElements[i]);
}
selectedElements = [];
selectedScopes = [];
if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
scope.$eval(attr.change);
forEach(selectedTranscludes, function(selectedTransclude) {
var selectedScope = scope.$new();
selectedScopes.push(selectedScope);
selectedTransclude.transclude(selectedScope, function(caseElement) {
var anchor = selectedTransclude.element;
selectedElements.push(caseElement);
animate.enter(caseElement, anchor.parent(), anchor);
});
});
}
});
}
}
}];
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 ngSwitchDefaultDirective = ngDirective({
transclude: 'element',
priority: 500,
require: '^ngSwitch',
compile: function(element, attrs, transclude) {
return function(scope, element, attr, ctrl) {
ctrl.cases['?'] = (ctrl.cases['?'] || []);
ctrl.cases['?'].push({ transclude: transclude, element: element });
};
}
});
|