angular-ui-bootstrap中的Collapse 指令源码解析

源码先放在这里,以后来补充,大部分注释写了,很好明白。

/*
 * angular-ui-bootstrap
 * http://angular-ui.github.io/bootstrap/

 * Version: 1.2.4 - 2016-03-06
 * License: MIT
 */angular.module("ui.bootstrap", ["ui.bootstrap.tpls","ui.bootstrap.collapse"]);
angular.module("ui.bootstrap.tpls", []);
angular.module('ui.bootstrap.collapse', [])

  .directive('uibCollapse', ['$animate', '$q', '$parse', '$injector', function($animate, $q, $parse, $injector) {
    var $animateCss = $injector.has('$animateCss') ? $injector.get('$animateCss') : null;
    return {
      link: function(scope, element, attrs) {
        var expandingExpr = $parse(attrs.expanding),//假如指令属性中有expanding方法,则用$attr获取
            expandedExpr = $parse(attrs.expanded),//假如属性中有expanded方法,则用$attr获取
            collapsingExpr = $parse(attrs.collapsing),//假如属性中有collapsingExpr方法,则用$attr获取
            collapsedExpr = $parse(attrs.collapsed);//假如属性中有collapsedExpr方法,则用$attr获取
//$parse和$eval都是解析字符串,区别是$parse是作为单独的一个服务存在,$eval是作为单独的一个scope方法来使用的
        if (!scope.$eval(attrs.uibCollapse)) {//如果uib-collapse为false的话,就为元素添加如下样式和属性
          element.addClass('in')
            .addClass('collapse')
            .attr('aria-expanded', true)
            .attr('aria-hidden', false)
            .css({height: 'auto'});
        }
//展开方法,由shouldCollapse负责监听,并且通过$q来达到展开折叠前后事件发生的控制
        function expand() {
          if (element.hasClass('collapse') && element.hasClass('in')) { //如果已经是展开的就返回
            return;
          }
//查到的资料显示 resolve是$q.deffer()的方法,不知这里为什么$q怎么回事。
          $q.resolve(expandingExpr(scope))//成功执行的信息,传递下去
            .then(function() {
              element.removeClass('collapse')
                .addClass('collapsing')
                .attr('aria-expanded', true)
                .attr('aria-hidden', false);

              if ($animateCss) {
                $animateCss(element, {
                  addClass: 'in',
                  easing: 'ease',
                  to: { height: element[0].scrollHeight + 'px' }
                }).start()['finally'](expandDone);
              } else {
                $animate.addClass(element, 'in', {
                  to: { height: element[0].scrollHeight + 'px' }
                }).then(expandDone);
              }
            });
        }

        function expandDone() {
          element.removeClass('collapsing')
            .addClass('collapse')
            .css({height: 'auto'});
          expandedExpr(scope);
        }

        function collapse() {
          if (!element.hasClass('collapse') && !element.hasClass('in')) {
            return collapseDone();
          }

          $q.resolve(collapsingExpr(scope))
            .then(function() {
              element
                // IMPORTANT: The height must be set before adding "collapsing" class.
                // Otherwise, the browser attempts to animate from height 0 (in
                // collapsing class) to the given height here.
                .css({height: element[0].scrollHeight + 'px'})
                // initially all panel collapse have the collapse class, this removal
                // prevents the animation from jumping to collapsed state
                .removeClass('collapse')
                .addClass('collapsing')
                .attr('aria-expanded', false)
                .attr('aria-hidden', true);

              if ($animateCss) {
                $animateCss(element, {
                  removeClass: 'in',
                  to: {height: '0'}
                }).start()['finally'](collapseDone);
              } else {
                $animate.removeClass(element, 'in', {
                  to: {height: '0'}
                }).then(collapseDone);
              }
            });
        }

        function collapseDone() {
          element.css({height: '0'}); // Required so that collapse works when animation is disabled
          element.removeClass('collapsing')
            .addClass('collapse');
          collapsedExpr(scope);
        }
//监听展开折叠变化
        scope.$watch(attrs.uibCollapse, function(shouldCollapse) {
          if (shouldCollapse) {
            collapse();
          } else {
            expand();
          }
        });
      }
    };
  }]);


你可能感兴趣的:(angular-ui-bootstrap中的Collapse 指令源码解析)