diff options
| author | Matias Niemelàˆ | 2013-07-11 20:58:23 -0400 | 
|---|---|---|
| committer | Misko Hevery | 2013-07-26 23:49:54 -0700 | 
| commit | 7d69d52acff8578e0f7d6fe57a6c45561a05b182 (patch) | |
| tree | 8751bfd8856d33363592f5da8adfb466a2142499 /src/ngRoute/directive | |
| parent | aa2133ad818d2e5c27cbd3933061797096356c8a (diff) | |
| download | angular.js-7d69d52acff8578e0f7d6fe57a6c45561a05b182.tar.bz2 | |
chore(ngView): $animate refactoring + transclusion & tests
BREAKING CHANGE: previously ngView only updated its content, after this change
ngView will recreate itself every time a new content is included. This ensures
that a single rootElement for all the included contents always exists, which makes
definition of css styles for animations much easier.
Diffstat (limited to 'src/ngRoute/directive')
| -rw-r--r-- | src/ngRoute/directive/ngView.js | 139 | 
1 files changed, 73 insertions, 66 deletions
| diff --git a/src/ngRoute/directive/ngView.js b/src/ngRoute/directive/ngView.js index 3074df49..c4add9ce 100644 --- a/src/ngRoute/directive/ngView.js +++ b/src/ngRoute/directive/ngView.js @@ -15,8 +15,10 @@ ngRouteModule.directive('ngView', ngViewFactory);   * configuration of the `$route` service.   *   * @animations - * enter - happens just after the ngView contents are changed (when the new view DOM element is inserted into the DOM) - * leave - happens just after the current ngView contents change and just before the former contents are removed from the DOM + * enter - animation is used to bring new content into the browser. + * leave - animation is used to animate existing content away. + * + * The enter and leave animation occur concurrently.   *   * @scope   * @example @@ -30,10 +32,9 @@ ngRouteModule.directive('ngView', ngViewFactory);            <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |            <a href="Book/Scarlet">Scarlet Letter</a><br/> -          <div -            ng-view -            class="example-$animate-container" -            ng-$animate="{enter: 'example-enter', leave: 'example-leave'}"></div> +          <div class="example-animate-container"> +            <div ng-view class="view-example"></div> +          </div>            <hr />            <pre>$location.path() = {{main.$location.path()}}</pre> @@ -60,20 +61,13 @@ ngRouteModule.directive('ngView', ngViewFactory);        </file>        <file name="animations.css"> -        .example-leave, .example-enter { +        .view-example {            -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;            -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;            -ms-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;            -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;            transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; -        } - -        .example-$animate-container { -          position:relative; -          height:100px; -        } -        .example-$animate-container > * {            display:block;            width:100%;            border-left:1px solid black; @@ -86,15 +80,20 @@ ngRouteModule.directive('ngView', ngViewFactory);            padding:10px;          } -        .example-enter { +        .example-animate-container { +          position:relative; +          height:100px; +        } + +        .view-example.ng-enter {            left:100%;          } -        .example-enter.example-enter-active { +        .view-example.ng-enter.ng-enter-active {            left:0;          } -        .example-leave { } -        .example-leave.example-leave-active { +        .view-example.ng-leave { } +        .view-example.ng-leave.ng-leave-active {            left:-100%;          }        </file> @@ -164,57 +163,65 @@ function ngViewFactory(   $route,   $anchorScroll,   $compile,   $controller,    return {      restrict: 'ECA',      terminal: true, -    link: function(scope, element, attr) { -      var lastScope, -          onloadExp = attr.onload || ''; - -      scope.$on('$routeChangeSuccess', update); -      update(); - - -      function destroyLastScope() { -        if (lastScope) { -          lastScope.$destroy(); -          lastScope = null; +    transclude: 'element', +    compile: function(element, attr, linker) { +      return function(scope, $element, attr) { +        var currentScope, +            currentElement, +            onloadExp = attr.onload || ''; + +        scope.$on('$routeChangeSuccess', update); +        update(); + +        function cleanupLastView() { +          if (currentScope) { +            currentScope.$destroy(); +            currentScope = null; +          } +          if(currentElement) { +            $animate.leave(currentElement); +            currentElement = null; +          }          } -      } - -      function clearContent() { -        $animate.leave(element.contents()); -        destroyLastScope(); -      } -      function update() { -        var locals = $route.current && $route.current.locals, -            template = locals && locals.$template; - -        if (template) { -          clearContent(); -          var enterElements = jqLite('<div></div>').html(template).contents(); -          $animate.enter(enterElements, element); - -          var link = $compile(enterElements), -              current = $route.current, -              controller; - -          lastScope = current.scope = scope.$new(); -          if (current.controller) { -            locals.$scope = lastScope; -            controller = $controller(current.controller, locals); -            if (current.controllerAs) { -              lastScope[current.controllerAs] = controller; -            } -            element.children().data('$ngControllerController', controller); +        function update() { +          var locals = $route.current && $route.current.locals, +              template = locals && locals.$template; + +          if (template) { +            var newScope = scope.$new(); +            linker(newScope, function(clone) { +              cleanupLastView(); + +              clone.html(template); +              $animate.enter(clone, null, $element); + +              var link = $compile(clone.contents()), +                  current = $route.current; + +              currentScope = current.scope = newScope; +              currentElement = clone; + +              if (current.controller) { +                locals.$scope = currentScope; +                var controller = $controller(current.controller, locals); +                if (current.controllerAs) { +                  currentScope[current.controllerAs] = controller; +                } +                clone.data('$ngControllerController', controller); +                clone.contents().data('$ngControllerController', controller); +              } + +              link(currentScope); +              currentScope.$emit('$viewContentLoaded'); +              currentScope.$eval(onloadExp); + +              // $anchorScroll might listen on event... +              $anchorScroll(); +            }); +          } else { +            cleanupLastView();            } - -          link(lastScope); -          lastScope.$emit('$viewContentLoaded'); -          lastScope.$eval(onloadExp); - -          // $anchorScroll might listen on event... -          $anchorScroll(); -        } else { -          clearContent();          }        }      } | 
