Skip to content

Commit e3f1736

Browse files
committed
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
1 parent 1b23b24 commit e3f1736

File tree

4 files changed

+32
-11
lines changed

4 files changed

+32
-11
lines changed

Diff for: sample/app/app.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,16 @@ angular.module('uiRouterSample', [
9494

9595
.state('me', {
9696
url: '/me',
97-
template: "<h1>Me, <a ui-sref=\"giserman\">Giserman</a></h1>"
97+
template: "<h1>Me, <a ui-sref=\"myself\">myself</a></h1>"
9898
})
9999

100-
.state('giserman', {
100+
.state('myself', {
101101
parent: 'me',
102102
independent: true,
103-
url: '/giserman',
103+
url: '/myself',
104104
views: {
105-
'giserman@': {
106-
template: "<h1>Giserman, <a ui-sref=\"^\">me</a></h1>"
105+
'myself@': {
106+
template: "<h1>Myself, <a ui-sref=\"^\">me</a></h1>"
107107
}
108108
}
109109
})

Diff for: sample/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
<!-- Here is the main ui-view (unnamed) and will be populated by its immediate children's templates
6363
unless otherwise explicitly named views are targeted. It's also employing ng-animate. -->
6464
<div ui-view class="container slide" style="padding-top: 80px;"></div>
65-
<div ui-view="giserman" class="container slide"></div>
65+
<div ui-view="myself" class="container slide"></div>
6666

6767

6868
<hr>

Diff for: src/state.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
2727
// Builds state properties from definition passed to registerState()
2828
var stateBuilder = {
2929

30+
// Independent child state inherits everything from it's parent, as usual, but won't render nor keep inherited views.
31+
independent: function(state) {
32+
if (isDefined(state.parent)) return isDefined(state.independent) ? state.independent : false;
33+
},
34+
3035
// Derive parent state from a hierarchical name only if 'parent' is not explicitly defined.
3136
// state.children = [];
3237
// if (parent) parent.children.push(state);
@@ -795,7 +800,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
795800
// Starting from the root of the path, keep all levels that haven't changed
796801
var keep = 0, state = toPath[keep], locals = root.locals, toLocals = [];
797802

798-
if (!options.reload) {
803+
// Force state to reload if coming from an independent child
804+
if (!options.reload && !from.self.independent) {
799805
while (state && state === fromPath[keep] && equalForKeys(toParams, fromParams, state.ownParams)) {
800806
locals = toLocals[keep] = state.locals;
801807
keep++;

Diff for: src/viewDirective.js

+19-4
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,13 @@ function $ViewDirective( $state, $injector, $uiViewScroll) {
204204
function updateView(firstTime) {
205205
var newScope = scope.$new(),
206206
name = currentEl && currentEl.data('$uiViewName'),
207-
previousLocals = name && $state.$current && $state.$current.locals[name];
207+
previousLocals = name && $state.$current && $state.$current.locals[name],
208+
independent = $state.$current.independent;
208209

209-
if (!firstTime && previousLocals === latestLocals) return; // nothing to do
210+
if ( (!firstTime && previousLocals === latestLocals) && !independent ) return; // nothing to do
210211

211212
var clone = $transclude(newScope, function(clone) {
213+
212214
renderer.enter(clone, $element, function onUiViewEnter() {
213215
if (angular.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) {
214216
$uiViewScroll(clone);
@@ -258,13 +260,26 @@ function $ViewDirectiveFill ($compile, $controller, $state) {
258260

259261
$element.data('$uiViewName', name);
260262

261-
var current = $state.$current,
262-
locals = current && current.locals[name];
263+
var current = $state.$current,
264+
locals = current && current.locals[name],
265+
independent = current.independent,
266+
split = [];
267+
268+
if (name.length > 1) split.push(name.split("@")[0]);
269+
else split.push(name);
263270

264271
if (! locals) {
265272
return;
266273
}
267274

275+
var template = locals.$template || initial;
276+
277+
if ( independent ) {
278+
if (split[0] !== locals.$$state.self.name) {
279+
template = null;
280+
}
281+
}
282+
268283
$element.data('$uiView', { name: name, state: locals.$$state });
269284
$element.html(locals.$template ? locals.$template : initial);
270285

0 commit comments

Comments
 (0)