From 1b23b2499c73936cb1dd705a2b07ad3be5135350 Mon Sep 17 00:00:00 2001 From: Gustavo Giserman Date: Tue, 19 Aug 2014 16:44:53 -0300 Subject: [PATCH 1/2] update sample app with new feature --- sample/app/app.js | 16 ++++++++++++++++ sample/index.html | 4 +++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sample/app/app.js b/sample/app/app.js index 10a82ecde..012db782f 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, Giserman

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

Giserman, me

" + } + } + }) } ] ); diff --git a/sample/index.html b/sample/index.html index 187ca7f80..f47a5f6d6 100644 --- a/sample/index.html +++ b/sample/index.html @@ -12,7 +12,7 @@ - +
  • Contacts
  • About
  • +
  • Me
  • +

    From c29c25c8c02a142bcfe3ef4a9cd63e0898d21d69 Mon Sep 17 00:00:00 2001 From: Gustavo Giserman Date: Tue, 19 Aug 2014 18:21:46 -0300 Subject: [PATCH 2/2] feat($state): "independent" (child) state implementation "independent" states must have defined parents (besides abstract "root") Prevent "independent" child state from rendering parent's template, but inherits everything as usual Forces state reload (render parent's views) when coming back from independent child state --- sample/app/app.js | 10 +++++----- sample/index.html | 4 ++-- src/state.js | 8 +++++++- src/viewDirective.js | 25 ++++++++++++++++++++----- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/sample/app/app.js b/sample/app/app.js index 012db782f..e50e54dee 100644 --- a/sample/app/app.js +++ b/sample/app/app.js @@ -94,16 +94,16 @@ angular.module('uiRouterSample', [ .state('me', { url: '/me', - template: "

    Me, Giserman

    " + template: "

    Me, myself

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

    Giserman, me

    " + 'myself@': { + template: "

    Myself, me

    " } } }) diff --git a/sample/index.html b/sample/index.html index f47a5f6d6..5caffe8db 100644 --- a/sample/index.html +++ b/sample/index.html @@ -12,7 +12,7 @@ - +
    -
    +

    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());