diff --git a/modules/angular1_router/src/ng_outlet.ts b/modules/angular1_router/src/ng_outlet.ts index 7ffcc543a2..ab7ea56580 100644 --- a/modules/angular1_router/src/ng_outlet.ts +++ b/modules/angular1_router/src/ng_outlet.ts @@ -145,7 +145,7 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) { } activate(instruction) { - let previousInstruction = this.currentInstruction; + this.previousInstruction = this.currentInstruction; this.currentInstruction = instruction; let componentName = this.controller.$$componentName = instruction.componentType; @@ -154,13 +154,14 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) { throw new Error('Component is not a string for ' + instruction.urlPath); } - this.controller.$$routeParams = instruction.params; this.controller.$$template = '<' + dashCase(componentName) + ' router="$$router">' + dashCase(componentName) + '>'; this.controller.$$router = this.router.childRouter(instruction.componentType); + this.controller.$$outlet = this; let newScope = scope.$new(); newScope.$$router = this.controller.$$router; + this.deferredActivation = $q.defer(); let clone = $transclude(newScope, clone => { $animate.enter(clone, null, this.currentElement || element); @@ -169,15 +170,7 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) { this.currentElement = clone; this.currentScope = newScope; - - // TODO: prefer the other directive retrieving the controller - // by debug mode - this.currentController = this.currentElement.children().eq(0).controller(componentName); - - if (this.currentController && this.currentController.$routerOnActivate) { - return this.currentController.$routerOnActivate(instruction, previousInstruction); - } - return $q.when(); + return this.deferredActivation.promise; } } @@ -200,21 +193,32 @@ function ngOutletFillContentDirective($compile) { link: (scope, element, attrs, ctrl) => { let template = ctrl.$$template; element.html(template); - let link = $compile(element.contents()); - link(scope); - - // TODO: move to primary directive - let componentInstance = scope[ctrl.$$componentName]; - if (componentInstance) { - ctrl.$$currentComponent = componentInstance; - - componentInstance.$router = ctrl.$$router; - componentInstance.$routeParams = ctrl.$$routeParams; - } + $compile(element.contents())(scope); } }; } + + +function routerTriggerDirective($q) { + return { + require: '^ngOutlet', + priority: -1000, + link: function(scope, element, attr, ngOutletCtrl) { + var promise = $q.when(); + var outlet = ngOutletCtrl.$$outlet; + var currentComponent = outlet.currentController = + element.controller(ngOutletCtrl.$$componentName); + if (currentComponent.$routerOnActivate) { + promise = $q.when(currentComponent.$routerOnActivate(outlet.currentInstruction, + outlet.previousInstruction)); + } + promise.then(outlet.deferredActivation.resolve, outlet.deferredActivation.reject); + } + }; +} + + /** * @name ngLink * @description @@ -289,7 +293,8 @@ function dashCase(str: string): string { angular.module('ngComponentRouter', []) .directive('ngOutlet', ['$animate', '$q', '$router', ngOutletDirective]) .directive('ngOutlet', ['$compile', ngOutletFillContentDirective]) - .directive('ngLink', ['$router', '$parse', ngLinkDirective]); + .directive('ngLink', ['$router', '$parse', ngLinkDirective]) + .directive('router', ['$q', routerTriggerDirective]); /* * A module for inspecting controller constructors diff --git a/modules/angular1_router/src/ng_route_shim.js b/modules/angular1_router/src/ng_route_shim.js index 5b60c24089..b471da3434 100644 --- a/modules/angular1_router/src/ng_route_shim.js +++ b/modules/angular1_router/src/ng_route_shim.js @@ -116,53 +116,41 @@ console.warn('Route for "' + path + '" should use "controllerAs".'); } - var directiveName = routeObjToRouteName(routeCopy, path); + var componentName = routeObjToRouteName(routeCopy, path); - if (!directiveName) { + if (!componentName) { throw new Error('Could not determine a name for route "' + path + '".'); } - routeDefinition.component = directiveName; - routeDefinition.name = route.name || upperCase(directiveName); + routeDefinition.component = componentName; + routeDefinition.name = route.name || upperCase(componentName); var directiveController = routeCopy.controller; - var directiveDefinition = { - scope: false, + var componentDefinition = { controller: directiveController, - controllerAs: routeCopy.controllerAs, - templateUrl: routeCopy.templateUrl, - template: routeCopy.template - }; + controllerAs: routeCopy.controllerAs - var directiveFactory = function () { - return directiveDefinition; }; + if (routeCopy.templateUrl) componentDefinition.templateUrl = routeCopy.templateUrl; + if (routeCopy.template) componentDefinition.template = routeCopy.template; + // if we have route resolve options, prepare a wrapper controller if (directiveController && routeCopy.resolve) { var originalController = directiveController; var resolvedLocals = {}; - directiveDefinition.controller = ['$injector', '$scope', function ($injector, $scope) { + componentDefinition.controller = ['$injector', '$scope', function ($injector, $scope) { var locals = angular.extend({ $scope: $scope }, resolvedLocals); - var ctrl = $injector.instantiate(originalController, locals); - - if (routeCopy.controllerAs) { - locals.$scope[routeCopy.controllerAs] = ctrl; - } - - return ctrl; + return $injector.instantiate(originalController, locals); }]; - // we take care of controllerAs in the directive controller wrapper - delete directiveDefinition.controllerAs; - // we resolve the locals in a canActivate block - directiveFactory.$canActivate = function() { + componentDefinition.$canActivate = function() { var locals = angular.extend({}, routeCopy.resolve); angular.forEach(locals, function(value, key) { @@ -179,7 +167,7 @@ } // register the dynamically created directive - $compileProvider.directive(directiveName, directiveFactory); + $compileProvider.component(componentName, componentDefinition); } if (subscriptionFn) { subscriptionFn(routeDefinition); diff --git a/modules/angular1_router/test/integration/animation_spec.js b/modules/angular1_router/test/integration/animation_spec.js index 513ca33e6c..1b95b3e556 100644 --- a/modules/angular1_router/test/integration/animation_spec.js +++ b/modules/angular1_router/test/integration/animation_spec.js @@ -25,7 +25,10 @@ describe('ngOutlet animations', function () { }); registerComponent('userCmp', { - template: '