forked from angular/angular.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathngSwitch.js
124 lines (120 loc) · 3.86 KB
/
ngSwitch.js
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
'use strict';
/**
* @ngdoc directive
* @name ng.directive:ngSwitch
* @restrict EA
*
* @description
* Conditionally change the DOM structure.
*
* @usageContent
* <ANY ng-switch-when="matchValue1">...</ANY>
* <ANY ng-switch-when="matchValue2">...</ANY>
* ...
* <ANY ng-switch-default>...</ANY>
*
* @scope
* @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
* @paramDescription
* On child elments 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 deafault', function() {
select('selection').option('other');
expect(element('.doc-example-live [ng-switch]').text()).toMatch(/default/);
});
</doc:scenario>
</doc:example>
*/
var NG_SWITCH = 'ng-switch';
var ngSwitchDirective = valueFn({
restrict: 'EA',
require: 'ngSwitch',
controller: function ngSwitchController() {
this.cases = {};
},
link: function(scope, element, attr, ctrl) {
var watchExpr = attr.ngSwitch || attr.on,
selectedTranscludes,
selectedElements,
selectedScopes;
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
forEach(selectedScopes, function(selectedScope) {
selectedScope.$destroy();
});
forEach(selectedElements, function(selectedElement) {
selectedElement.remove();
});
selectedElements = [];
selectedScopes = [];
if ((selectedTranscludes = ctrl.cases['!' + value] || ctrl.cases['?'])) {
scope.$eval(attr.change);
forEach(selectedTranscludes, function(selectedTransclude) {
var selectedScope = scope.$new();
selectedScopes.push(selectedScope);
selectedTransclude(selectedScope, function(caseElement) {
selectedElements.push(caseElement);
element.append(caseElement);
});
});
}
});
}
});
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);
};
}
});
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);
};
}
});