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: "
"
+ })
+
+ .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());