8
votes

I needs to apply an "active" class to a bootstrap tab depending on the current route name. The route object contains "routeName" but how to I access this from a controller or component?

7
May this this.controllerFor('application').get('currentRouteName')blessenm
@blessenm yep, that is pretty much what I wantjax
ember will do this for you. just use link-to on your tabskillebytes
Ember.getOwner(this).lookup(‘controller:application’).currentPath; Refer: discuss.emberjs.com/t/ember-get-current-route-name/10324Alan Dong

7 Answers

9
votes

Use this this.controllerFor('application').get('currentRouteName');

5
votes

In fact, you don't need to apply active class by yourself. A link-to helper will do it for you.

See here:

{{link-to}} will apply a CSS class name of 'active' when the application's current route matches the supplied routeName. For example, if the application's current route is 'photoGallery.recent' the following use of {{link-to}}:

{{#link-to 'photoGallery.recent'}}
  Great Hamster Photos
{{/link-to}}

will result in

<a href="/hamster-photos/this-week" class="active">
  Great Hamster Photos
</a>
4
votes

In the absolutely desperate case, you can look up the router, or the application controller (which exposes a 'currentRouteName' property) via this.container.lookup("router:main") or this.container.lookup("controller:application") from within the component.

If it was a common trend for me, I would make a CurrentRouteService and inject it into my component(s) so that I can mock things more easily in my tests.

There may also be a better answer to come along - but the container.lookup() should knock down your current blocker.

4
votes

Since Ember 2.15 you can do this through the public Router service.

router: service(),
myRouteName: computed('router.currentRouteName', function () {
    return this.get('router.currentRouteName') + 'some modification';
}

https://www.emberjs.com/api/ember/release/classes/RouterService

Which worked really well for me since I wanted something computed off of the current route. The service exposes currentRouteName, currentURL, location, and rootURL.

currentURL has the query params, but you would need to parse them from the URL.

3
votes

For Ember 2, from a controller you can try :

appController: Ember.inject.controller('application'),
currentRouteName: Ember.computed.reads('appController.currentRouteName')

Then you can pass it to component.

1
votes

Try this.

export default Ember.Route.extend({
  routeName: null,
  
  beforeModel(transition){
    //alert(JSON.stringify(transition.targetName) + 'typeof' + typeof transition.targetName);
    this.set('routeName', transition.targetName);
  },
  model(){

   // write your logic here to determine which one to set 'active' or pass the routeName to controller or component
  }

`

0
votes

Using insights from @maharaja-santhir's answer, one can think of setting the routeName property on the target controller to use, e.g., in the target's template. This way there's no need for defining the logic in multiple locations and hence code-reusability. Here's an example of how to accomplish that:

// app/routes/application.js
export default Ember.Route.extend({
    ...

    actions: {
        willTransition(transition) {
            let targetController = this.controllerFor(transition.targetName);
            set(targetController, 'currentRouteName', transition.targetName);
            return true;
        }
    }
});

Defining this willTransition action in the application route allows for propagating the current route name to anywhere in the application. Note that the target controller will retain the currentRouteName property setting even after navigating away to another route. This requires manual cleanup, if needed, but it might be acceptable depending on your implementation and use case.