mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
189 lines
6.5 KiB
JavaScript
189 lines
6.5 KiB
JavaScript
'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.
|
|
*
|
|
* @animations
|
|
* enter - happens after the ngSwitch 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
|
|
* @priority 800
|
|
* @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
|
|
<example animations="true">
|
|
<file name="index.html">
|
|
<div ng-controller="Ctrl">
|
|
<select ng-model="selection" ng-options="item for item in items">
|
|
</select>
|
|
<tt>selection={{selection}}</tt>
|
|
<hr/>
|
|
<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-default>default</div>
|
|
</div>
|
|
</div>
|
|
</file>
|
|
<file name="script.js">
|
|
function Ctrl($scope) {
|
|
$scope.items = ['settings', 'home', 'other'];
|
|
$scope.selection = $scope.items[0];
|
|
}
|
|
</file>
|
|
<file name="animations.css">
|
|
.animate-switch-container {
|
|
position:relative;
|
|
background:white;
|
|
border:1px solid black;
|
|
height:40px;
|
|
overflow:hidden;
|
|
}
|
|
|
|
.animate-switch-container > div {
|
|
padding:10px;
|
|
}
|
|
|
|
.animate-switch-container > .ng-enter,
|
|
.animate-switch-container > .ng-leave {
|
|
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
|
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
|
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
|
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
|
|
|
position:absolute;
|
|
top:0;
|
|
left:0;
|
|
right:0;
|
|
bottom:0;
|
|
}
|
|
|
|
.animate-switch-container > .ng-enter {
|
|
top:-50px;
|
|
}
|
|
.animate-switch-container > .ng-enter.ng-enter-active {
|
|
top:0;
|
|
}
|
|
|
|
.animate-switch-container > .ng-leave {
|
|
top:0;
|
|
}
|
|
.animate-switch-container > .ng-leave.ng-leave-active {
|
|
top:50px;
|
|
}
|
|
</file>
|
|
<file name="scenario.js">
|
|
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/);
|
|
});
|
|
</file>
|
|
</example>
|
|
*/
|
|
var ngSwitchDirective = ['$animate', function($animate) {
|
|
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 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: 800,
|
|
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: 800,
|
|
require: '^ngSwitch',
|
|
compile: function(element, attrs, transclude) {
|
|
return function(scope, element, attr, ctrl) {
|
|
ctrl.cases['?'] = (ctrl.cases['?'] || []);
|
|
ctrl.cases['?'].push({ transclude: transclude, element: element });
|
|
};
|
|
}
|
|
});
|