AngularJS 指令之 ng-switch

用途

ng-switch 属性用来根据一个范围的值来控制页面内元素的添加或移除。子元素必须配合ng-switch-when或ng-switch-default来使用,否则ng-switch将被忽略。

用法 
 
<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 class="animate-switch" ng-switch-when="settings">Settings Div</div>
      <div class="animate-switch" ng-switch-when="home">Home Span</div>
      <div class="animate-switch" ng-switch-default>default</div>
  </div>
</div>

 上述实例中,on属性可以不写,直接将swich的对象表达式设置到 ng-swtich属性:

 <div class="animate-switch-container"  ng-switch="selection">

实在不解作者为啥这么设计!从源代码以及使用效果来看,on属性完全是多余的。难不成历史遗留?

另外一点也需要特别注意:

ng-switch接收表达式(如上例中的$scope.selection,而ng-switch-when接收的是字符串值而不是表达式。譬如:ng-switch-when="someVal" 将匹配字符串 "someVal" 而不是$scope.someVal的值。这点和js中的switch的用法是一样的:switch变量,case指定值。

  

工作原理

ng-switch由三个子指令组成: ng-switch,ng-switch-when以及ng-switch-default。

ng-switch-when指令和ng-switch-default指令比较简单,将监视的字符串以及元素添加到父元素ng-switch的controller的cases中去。

ng-switch指令监视表达式的变化,变化后将当前元素移除,将ontroller的cases中的符合要求的元素添加到页面。

ng-switch的核心代码: 

var ngSwitchDirective = ['$animate', function($animate) {
  return {
    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
      scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
        var i, ii;
        for (i = 0, ii = previousLeaveAnimations.length; i < ii; ++i) {
          $animate.cancel(previousLeaveAnimations[i]);
        }for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
          var selected = getBlockNodes(selectedElements[i].clone);
          selectedScopes[i].$destroy();
          var promise = previousLeaveAnimations[i] = $animate.leave(selected);
          promise.then(spliceFactory(previousLeaveAnimations, i));
        }
if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
          forEach(selectedTranscludes, function(selectedTransclude) {
            selectedTransclude.transclude(function(caseElement, selectedScope) {
              selectedScopes.push(selectedScope);
              var anchor = selectedTransclude.element;
              caseElement[caseElement.length++] = document.createComment(' end ngSwitchWhen: ');
              var block = { clone: caseElement };

              selectedElements.push(block);
              $animate.enter(caseElement, anchor.parent(), anchor);
            });
          });
        }
      });
    }
  };
}];

var ngSwitchWhenDirective = ngDirective({
  transclude: 'element',
  priority: 1200,
  require: '^ngSwitch',
  multiElement: true,
  link: function(scope, element, attrs, ctrl, $transclude) {
    ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
    ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: $transclude, element: element });
  }
});

var ngSwitchDefaultDirective = ngDirective({
  transclude: 'element',
  priority: 1200,
  require: '^ngSwitch',
  multiElement: true,
  link: function(scope, element, attr, ctrl, $transclude) {
    ctrl.cases['?'] = (ctrl.cases['?'] || []);
    ctrl.cases['?'].push({ transclude: $transclude, element: element });
   }
});

  

原文地址:https://www.cnblogs.com/itman70s/p/ngswitch.html