refactor($route): remove .parent(); ng:view scope creation

This commit is contained in:
Misko Hevery 2012-02-15 21:49:07 -08:00 committed by Vojta Jina
parent f16bd2f747
commit e31d1c287d
6 changed files with 67 additions and 45 deletions

View file

@ -36,16 +36,17 @@ The two partials are defined in the following URLs:
* <a href="./examples/settings.html" ng:ext-link>./examples/settings.html</a>
* <a href="./examples/welcome.html" ng:ext-link>./examples/welcome.html</a>
<doc:example>
<doc:example module="deepLinking">
<doc:source jsfiddle="false">
<script>
angular.module('deepLinking', [])
.config(function($routeProvider) {
$routeProvider.when("/welcome", {template:'./examples/welcome.html', controller:WelcomeCntl});
$routeProvider.when("/settings", {template:'./examples/settings.html', controller:SettingsCntl});
});
AppCntl.$inject = ['$scope', '$route']
function AppCntl($scope, $route) {
// define routes
$route.when("/welcome", {template:'./examples/welcome.html', controller:WelcomeCntl});
$route.when("/settings", {template:'./examples/settings.html', controller:SettingsCntl});
$route.parent($scope);
// initialize the model to something useful
$scope.person = {
name:'anonymous',

View file

@ -135,8 +135,8 @@ function $RouteProvider(){
};
this.$get = ['$rootScope', '$location', '$routeParams', '$controller',
function( $rootScope, $location, $routeParams, $controller) {
this.$get = ['$rootScope', '$location', '$routeParams',
function( $rootScope, $location, $routeParams) {
/**
* @ngdoc event
* @name angular.module.ng.$route#$beforeRouteChange
@ -185,28 +185,11 @@ function $RouteProvider(){
*/
var matcher = switchRouteMatcher,
parentScope = $rootScope,
dirty = 0,
forceReload = false,
$route = {
routes: routes,
/**
* @ngdoc method
* @name angular.module.ng.$route#parent
* @methodOf angular.module.ng.$route
*
* @param {Scope} [scope=rootScope] Scope to be used as parent for newly created
* `$route.current.scope` scopes.
*
* @description
* Sets a scope to be used as the parent scope for scopes created on route change. If not
* set, defaults to the root scope.
*/
parent: function(scope) {
if (scope) parentScope = scope;
},
/**
* @ngdoc method
* @name angular.module.ng.$route#reload
@ -266,7 +249,10 @@ function $RouteProvider(){
} else {
forceReload = false;
$rootScope.$broadcast('$beforeRouteChange', next, last);
last && last.scope && last.scope.$destroy();
if (last && last.scope) {
last.scope.$destroy();
last.scope = null;
}
$route.current = next;
if (next) {
if (next.redirectTo) {
@ -279,10 +265,6 @@ function $RouteProvider(){
}
} else {
copy(next.params, $routeParams);
next.scope = parentScope.$new();
if (next.controller) {
$controller(next.controller, {$scope: next.scope});
}
}
}
$rootScope.$broadcast('$afterRouteChange', next, last);

View file

@ -574,7 +574,7 @@ function $RootScopeProvider(){
*
* The event listener function format is: `function(event)`. The `event` object passed into the
* listener has the following attributes
*
*
* - `targetScope` - {Scope}: the scope on which the event was `$emit`-ed or `$broadcast`-ed.
* - `currentScope` - {Scope}: the current scope which is handling the event.
* - `name` - {string}: Name of the event.

View file

@ -498,23 +498,23 @@ var ngNonBindableDirective = valueFn({ terminal: true });
*
*
* @example
<doc:example>
<doc:example module="ngView">
<doc:source jsfiddle="false">
<script>
function MyCtrl($route) {
$route.when('/overview',
{ controller: OverviewCtrl,
template: 'partials/guide/dev_guide.overview.html'});
$route.when('/bootstrap',
{ controller: BootstrapCtrl,
template: 'partials/guide/dev_guide.bootstrap.auto_bootstrap.html'});
};
MyCtrl.$inject = ['$route'];
function BootstrapCtrl() {}
function OverviewCtrl() {}
angular.module('ngView', [])
.config(function($routeProvider) {
$routeProvider.when('/overview',
{ controller: OverviewCtrl,
template: 'partials/guide/dev_guide.overview.html'});
$routeProvider.when('/bootstrap',
{ controller: BootstrapCtrl,
template: 'partials/guide/dev_guide.bootstrap.auto_bootstrap.html'});
});
</script>
<div ng:controller="MyCtrl">
<div>
<a href="overview">overview</a> |
<a href="bootstrap">bootstrap</a> |
<a href="undefined">undefined</a>
@ -538,14 +538,18 @@ var ngNonBindableDirective = valueFn({ terminal: true });
</doc:example>
*/
var ngViewDirective = ['$http', '$templateCache', '$route', '$anchorScroll', '$compile',
function($http, $templateCache, $route, $anchorScroll, $compile) {
'$controller',
function($http, $templateCache, $route, $anchorScroll, $compile,
$controller) {
return {
terminal: true,
link: function(scope, element) {
var changeCounter = 0;
scope.$on('$afterRouteChange', function() {
processRoute($route.current);
scope.$on('$afterRouteChange', function(event, next) {
changeCounter++;
processRoute(next);
});
scope.$watch(function() {return changeCounter;}, function(newChangeCounter) {
@ -571,6 +575,15 @@ var ngViewDirective = ['$http', '$templateCache', '$route', '$anchorScroll', '$c
clearContent();
}
});
function processRoute(route) {
if (route) {
route.scope = scope.$new();
if (route.controller) {
$controller(route.controller, {$scope: route.scope});
}
}
}
}
};
}];

View file

@ -1,6 +1,20 @@
'use strict';
describe('$route', function() {
beforeEach(module(function() {
return function($rootScope, $controller) {
$rootScope.$on('$afterRouteChange', function(event, next) {
// emulate ng:view scope creation
if (next) {
next.scope = $rootScope.$new();
next.controller && $controller(next.controller, {$scope: next.scope});
}
});
};
}));
it('should route and fire change event', function() {
var log = '',
lastRoute,

View file

@ -633,6 +633,18 @@ describe('widget', function() {
}));
it('should create controller instance on $afterRouteChange event', inject(
function($route, $rootScope) {
var controllerScope;
$route.current = { controller: function($scope) { controllerScope = $scope; } };
$rootScope.$broadcast('$afterRouteChange', $route.current);
expect(controllerScope.$parent.$id).toBe($rootScope.$id);
expect(controllerScope.$id).toBe($route.current.scope.$id);
}
));
it('should load content via xhr when route changes', function() {
module(function($routeProvider) {
$routeProvider.when('/foo', {template: 'myUrl1'});