diff options
| author | Tobias Bosch | 2013-12-10 16:45:54 -0800 | 
|---|---|---|
| committer | Tobias Bosch | 2013-12-12 17:18:44 -0800 | 
| commit | f8944efe70b81e02704df9b53ea2546c80c73d3b (patch) | |
| tree | 6480df5a9b7a1ea65dabe3d2247c7e16fa9b8afb /src/ngRoute/directive/ngView.js | |
| parent | 43072e3812e32b89b97ad03144577cba50d4b776 (diff) | |
| download | angular.js-f8944efe70b81e02704df9b53ea2546c80c73d3b.tar.bz2 | |
fix(ngView): Add template to DOM before linking other directives
The template needs to be added to the DOM before
other directives at the same element as `ngView` are linked.
Related to #5247.
Diffstat (limited to 'src/ngRoute/directive/ngView.js')
| -rw-r--r-- | src/ngRoute/directive/ngView.js | 74 | 
1 files changed, 47 insertions, 27 deletions
| diff --git a/src/ngRoute/directive/ngView.js b/src/ngRoute/directive/ngView.js index 280bf423..b1252944 100644 --- a/src/ngRoute/directive/ngView.js +++ b/src/ngRoute/directive/ngView.js @@ -1,6 +1,8 @@  'use strict';  ngRouteModule.directive('ngView', ngViewFactory); +ngRouteModule.directive('ngView', ngViewFillContentFactory); +  /**   * @ngdoc directive @@ -166,8 +168,8 @@ ngRouteModule.directive('ngView', ngViewFactory);   * @description   * Emitted every time the ngView content is reloaded.   */ -ngViewFactory.$inject = ['$route', '$anchorScroll', '$compile', '$controller', '$animate']; -function ngViewFactory(   $route,   $anchorScroll,   $compile,   $controller,   $animate) { +ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate']; +function ngViewFactory(   $route,   $anchorScroll,   $animate) {    return {      restrict: 'ECA',      terminal: true, @@ -199,6 +201,7 @@ function ngViewFactory(   $route,   $anchorScroll,   $compile,   $controller,            if (template) {              var newScope = scope.$new(); +            var current = $route.current;              // Note: This will also link all children of ng-view that were contained in the original              // html. If that content contains controllers, ... they could pollute/change the scope. @@ -206,34 +209,18 @@ function ngViewFactory(   $route,   $anchorScroll,   $compile,   $controller,              // Note: We can't remove them in the cloneAttchFn of $transclude as that              // function is called before linking the content, which would apply child              // directives to non existing elements. -            var clone = $transclude(newScope, angular.noop); -            clone.html(template); -            $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () { -              if (angular.isDefined(autoScrollExp) -                && (!autoScrollExp || scope.$eval(autoScrollExp))) { -                $anchorScroll(); -              } +            var clone = $transclude(newScope, function(clone) { +              $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () { +                if (angular.isDefined(autoScrollExp) +                  && (!autoScrollExp || scope.$eval(autoScrollExp))) { +                  $anchorScroll(); +                } +              }); +              cleanupLastView();              }); -            cleanupLastView(); - -            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.children().data('$ngControllerController', controller); -            } - -            link(currentScope); +            currentScope = current.scope = newScope;              currentScope.$emit('$viewContentLoaded');              currentScope.$eval(onloadExp);            } else { @@ -243,3 +230,36 @@ function ngViewFactory(   $route,   $anchorScroll,   $compile,   $controller,      }    };  } + +// This directive is called during the $transclude call of the first `ngView` directive. +// It will replace and compile the content of the element with the loaded template. +// We need this directive so that the element content is already filled when +// the link function of another directive on the same element as ngView +// is called. +ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route']; +function ngViewFillContentFactory($compile, $controller, $route) { +  return { +    restrict: 'ECA', +    priority: -400, +    link: function(scope, $element) { +      var current = $route.current, +          locals = current.locals; + +      $element.html(locals.$template); + +      var link = $compile($element.contents()); + +      if (current.controller) { +        locals.$scope = scope; +        var controller = $controller(current.controller, locals); +        if (current.controllerAs) { +          scope[current.controllerAs] = controller; +        } +        $element.data('$ngControllerController', controller); +        $element.children().data('$ngControllerController', controller); +      } + +      link(scope); +    } +  }; +} | 
