最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - UI-router accessing parent state from child - Stack Overflow

programmeradmin0浏览0评论

I'd like to set the title based on the state in my angular app. It works nicely, but if there's no title defined on the child state, I'd like to fall back to the parent's title property.

This is what I have so far:

In my app run block:

...
$rootScope.$on('$stateChangeSuccess', function (event, current, previous) {

  if (current.hasOwnProperty('title')) {
    $rootScope.title = current.title;
  }
});
...

In my module's route

.state('main.parent', {
  url: '/parent',
  controller: 'ParentController',
  controllerAs: 'vm',
  templateUrl: 'app/parent.html',
  title: 'Parent',
})
.state('main.parent.child', {
  url: '/child',
  controller: 'ChildController',
  controllerAs: 'vm',
  templateUrl: 'app/child.html'
})

During the code inspection, I found that $stateChangeSuccess is triggered twice as expected, first for the parent and then for the child. I tried to access current.parent when the child was called, but it has no such property. Is there any way to access it?

UPDATE

I saw these questions: get parent state from ui-router $stateChangeStart, get parent state from ui-router $stateChangeStart But none of them had a clear answer to this problem (except the state splitting hack in the latter one but I'd rather avoid that).

I'd like to set the title based on the state in my angular app. It works nicely, but if there's no title defined on the child state, I'd like to fall back to the parent's title property.

This is what I have so far:

In my app run block:

...
$rootScope.$on('$stateChangeSuccess', function (event, current, previous) {

  if (current.hasOwnProperty('title')) {
    $rootScope.title = current.title;
  }
});
...

In my module's route

.state('main.parent', {
  url: '/parent',
  controller: 'ParentController',
  controllerAs: 'vm',
  templateUrl: 'app/parent.html',
  title: 'Parent',
})
.state('main.parent.child', {
  url: '/child',
  controller: 'ChildController',
  controllerAs: 'vm',
  templateUrl: 'app/child.html'
})

During the code inspection, I found that $stateChangeSuccess is triggered twice as expected, first for the parent and then for the child. I tried to access current.parent when the child was called, but it has no such property. Is there any way to access it?

UPDATE

I saw these questions: get parent state from ui-router $stateChangeStart, get parent state from ui-router $stateChangeStart But none of them had a clear answer to this problem (except the state splitting hack in the latter one but I'd rather avoid that).

Share Improve this question edited May 23, 2017 at 12:16 CommunityBot 11 silver badge asked Oct 24, 2016 at 9:32 fodma1fodma1 3,5351 gold badge31 silver badges51 bronze badges 1
  • 1 check with $state.$current.parent! – Pravin Erande Commented Oct 24, 2016 at 9:46
Add a ment  | 

5 Answers 5

Reset to default 5

The both ways are hacks a bit. Don't forget to import $state (and $stateParams for 2nd variant) providers in your controller. You can use:

$state.$current.parent.self.title 

or

var tree = current.name.split('.');
tree.splice(tree.length-1, 1);
var parent = tree.join('.');
$state.get(parent, $stateParams);

It seems that you just need the title property to fall back to the parent's title property if there's no title defined on the child state, I will suggest you to use this repository: angular-ui-router-title.

So finally I came up with the following solution:

I store title inside the state's data object, because from $state you can't access the parent's custom properties, only the ones stored in data (which makes sense - not to pollute the state definition with custom properties).

.state('main.parent', {
  url: '/parent',
  controller: 'ParentController',
  controllerAs: 'vm',
  templateUrl: 'app/parent.html',
  data: {
    title: 'Parent'
  }
})
.state('main.parent.child', {
  url: '/child',
  controller: 'ChildController',
  controllerAs: 'vm',
  templateUrl: 'app/child.html'
})

And I changed the runblock as follows:

...
$rootScope.$on('$stateChangeSuccess', function (event, toState, fromState) {
  var current = $state.$current;
  if (current.data.hasOwnProperty('title')) {
    $rootScope.title = current.data.title;
  } else if(current.parent && current.parent.data.hasOwnProperty('title')) {
    $rootScope.title = current.parent.data.title;
  } else {
    $rootScope.title = null;
  }
});
...

This is not the perfect solution yet, as in the case of multiple nested states it'd be nice to fall back to the title of the youngest ancestor's title but it does it for now.

Simply below code is working for me

$state.$current.parent

Looking at the UI-Router documentation in the "to" section, you could do something like below:

$state.go('^');

to go back to the parent state.

发布评论

评论列表(0)

  1. 暂无评论