0
votes

So here's the thing. I have this ng-class on my header item for projects:

ng-class="{ active: $state.includes('project')}"

My main view for projects is called home, the projects themselves are actually under an abstract project state.

Home:

.state('home', {
  url: '/',
  templateUrl: '/views/project-list-view.html',
  controller: 'ProjectListCtrl'
})

Project:

.state('project', {
  template: '<ui-view/>',
  url: '/project',
  abstract: true,
  controller: function ($scope) {
    //
  }
})
.state('project.view', {
  url: '/:slug',
  params: {
    id: null,
    slug: null
  },
  templateUrl: '/views/project-view.html',
  controller: 'ProjectViewCtrl'
})

So the problem with this is that when I navigate from my home state (project list) to the project view page, the menu item loses it's active class. When I refresh the page after navigating, it works though. Why is this not working properly and how do I overcome this?

Edit: Had ui-sref-active in the title, but that is not the relevant part that's breaking.

Edit2: http://plnkr.co/edit/kwLBOFgBz0dYaKnavSum?p=preview

2
You can't get it to work like that. Because you move from the home state to the project state, so of course, home is not active anymore and neither includes project state. To get what you want, you'll have to define .state('project') as your root/home. So instead of .state('home') change it to .state('project') - Razvan B.
How can I have the root page (being the project list) to have "/" as the url and the other project (sub-) pages to have the /project prefix? Having multiple slashes in routes break the app when refreshing, so I can't just have "/project/id/" as a route. - user1740375
And the issue is actually that my current solution almost works, I mean, after refreshing the page after the route change it works, so it means there must be something I can trigger somewhere to fix this, right? - user1740375
Why do you even have "ui-sref-active=active" tag in ur <li>'s when you have ng-class in it. Please remove this ui-sref-active="active" from the <li>. Something like below : <li ui-sref="home" ng-class="{ active: $state.includes('project')}">Link to somewhere</li> - Vaibhav Pachauri
Because of the "home" state, that is linked through the route. I want other states ('project' and its sub-states) to also make it active, that's why I have the ng-class there. - user1740375

2 Answers

0
votes

Doing it your way, what you can do is create a Run Block for your app and everytime you change the route, look to see if it includes the project state:

app.run(['$rootScope', '$state', function($rootScope, $state) {

  $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {

    $rootScope.projectState = $state.includes('project') || $state.includes('home');

  });

}]);

Then, in your index file:

<!-- remove ui-sref-active -->
<li ui-sref="home" ng-class="projectState ? 'active' : '' ">Link to somewhere</li>

And here is your modified plunker

0
votes

In your check you use $state.includes (API reference with example) which check if the state includes previous one. Which is true project.view includes project as a parent state.

You should use $state.is() instead of such check.