diff --git a/sample/app/app.js b/sample/app/app.js index 10a82ecde..e50e54dee 100644 --- a/sample/app/app.js +++ b/sample/app/app.js @@ -91,6 +91,22 @@ angular.module('uiRouterSample', [ }, 100); }] }) + + .state('me', { + url: '/me', + template: "

Me, myself

" + }) + + .state('myself', { + parent: 'me', + independent: true, + url: '/myself', + views: { + 'myself@': { + template: "

Myself, me

" + } + } + }) } ] ); diff --git a/sample/index.html b/sample/index.html index 187ca7f80..5caffe8db 100644 --- a/sample/index.html +++ b/sample/index.html @@ -50,6 +50,7 @@ its descendant states are activated. -->
  • Contacts
  • About
  • +
  • Me
  • +

    diff --git a/src/state.js b/src/state.js index 1986b1b22..d4eaca29b 100644 --- a/src/state.js +++ b/src/state.js @@ -27,6 +27,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { // Builds state properties from definition passed to registerState() var stateBuilder = { + // Independent child state inherits everything from it's parent, as usual, but won't render nor keep inherited views. + independent: function(state) { + if (isDefined(state.parent)) return isDefined(state.independent) ? state.independent : false; + }, + // Derive parent state from a hierarchical name only if 'parent' is not explicitly defined. // state.children = []; // if (parent) parent.children.push(state); @@ -795,7 +800,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { // Starting from the root of the path, keep all levels that haven't changed var keep = 0, state = toPath[keep], locals = root.locals, toLocals = []; - if (!options.reload) { + // Force state to reload if coming from an independent child + if (!options.reload && !from.independent) { while (state && state === fromPath[keep] && equalForKeys(toParams, fromParams, state.ownParams)) { locals = toLocals[keep] = state.locals; keep++; diff --git a/src/viewDirective.js b/src/viewDirective.js index 3610025f6..8dd448b2a 100644 --- a/src/viewDirective.js +++ b/src/viewDirective.js @@ -204,11 +204,13 @@ function $ViewDirective( $state, $injector, $uiViewScroll) { function updateView(firstTime) { var newScope = scope.$new(), name = currentEl && currentEl.data('$uiViewName'), - previousLocals = name && $state.$current && $state.$current.locals[name]; + previousLocals = name && $state.$current && $state.$current.locals[name], + independent = $state.$current.independent; - if (!firstTime && previousLocals === latestLocals) return; // nothing to do + if ( (!firstTime && previousLocals === latestLocals) && !independent ) return; // nothing to do var clone = $transclude(newScope, function(clone) { + renderer.enter(clone, $element, function onUiViewEnter() { if (angular.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) { $uiViewScroll(clone); @@ -258,15 +260,28 @@ function $ViewDirectiveFill ($compile, $controller, $state) { $element.data('$uiViewName', name); - var current = $state.$current, - locals = current && current.locals[name]; + var current = $state.$current, + locals = current && current.locals[name], + independent = current.independent, + split = []; + + if (name.length > 1) split.push(name.split("@")[0]); + else split.push(name); if (! locals) { return; } + var template = locals.$template || initial; + + if ( independent ) { + if (split[0] !== locals.$$state.self.name) { + template = null; + } + } + $element.data('$uiView', { name: name, state: locals.$$state }); - $element.html(locals.$template ? locals.$template : initial); + $element.html(template); var link = $compile($element.contents());