Sambeau
Sambeau

Reputation: 254

Getting the active route and applying it to a nav in a view

I've been trying to work out how to wire up my navigation and show which nav item is active. I have a view for it here:

  <script type="text/x-handlebars" data-template-name="nav">
  <ul class="nav">
    <li>{{#linkTo "index"}}Index{{/linkTo}}</li>
    <li>{{#linkTo "lunches"}}Lunches{{/linkTo}}</li>
    <li>{{#linkTo "people"}}People{{/linkTo}}</li>
  </ul>
  </script>

I'm using Bootstrap and bootstrap puts the 'active' class on the <li> rather than the <a>. Ember by default puts it on the <a>. I've tried all sorts of things to try to get the active route and apply it to this view (and I've tried manually setting a value and applying it with a handlebars.helper but it was a mess of metamorphs).

What is the 'correct' Ember way here?

I confess I'm getting lost at all three main points:

  1. Getting the value from the Route
  2. Moving the value into from Route to view (or binding it across)
  3. Displaying the value as an attribute without metamorphs in my tag

Clearly I'm making a lot of fundamental errors here. Could someone please put me right.

Upvotes: 3

Views: 2667

Answers (3)

Sambeau
Sambeau

Reputation: 254

A better answer to this can be found on this thread.

I particularly like this answer:

{{#linkTo "dashboard" tagName="li"}}
    <a {{bindAttr href="view.href"}}>Dashboard</a>
{{/linkTo}}

Upvotes: 2

Sambeau
Sambeau

Reputation: 254

Here's what I ended up doing. It works but it seems way too complicated so I suspect it is fundamentally flawed. Any corrections and/or improvements would be very welcome.

Here's the view to create the nav bar:

  <script type="text/x-handlebars" data-template-name="nav">
    <ul class="nav">
      {{#each navs}}
          <li {{bindAttr class="isActive:active"}}><a href="#" {{action select link}}> {{title}}</a></li>
      {{/each}}
    </ul>
  </script>

and here's the vast amount of code to drive it :)

App.ApplicationController = Ember.Controller.extend({
    active: 'index'
}); 


App.ApplicationRoute = Ember.Route.extend({
    setupController: function(){
        var active = this.controllerFor('application').get('active');
        this.controllerFor('nav').set('model',{
            active:'index',
            navs: [
                { link:"index",   title:'Toad',    isActive: active === 'index' },
                { link:"lunches", title:'Lunches', isActive: active === 'lunches' },
                { link:"people",  title:'People',  isActive: active === 'people' }
            ]
        });
    },
    events: {
        select: function (item) {
            var nav = this.controllerFor('nav');
            var app = this.controllerFor('application');
            app.set('active',item);
            var active = app.get('active');
            var navs = nav.get('navs');
            new_navs = [];
            for (var i = navs.length - 1; i >= 0; i--) {
                new_navs[i] = { link: navs[i].link, title: navs[i].title, isActive: active === navs[i].link} ;
            };
            nav.set('navs',new_navs);
            this.transitionTo(item);
        }
    }
});

App.NavController = Ember.ObjectController.extend({

});


// Routes

App.Router.map(function() {
  this.route("people");
  this.route("lunches");
});

App.PeopleRoute = Ember.Route.extend({
    setupController: function(controller, model) {
        this.send('select','people');
        controller.set('people', App.People.find());
    },
});

App.LunchesRoute = Ember.Route.extend({
    setupController: function(controller, model) {
        this.send('select','lunches');
        controller.set('lunches', App.Event.find());
    },
});

Please, do your worst, tear this apart and put me right!

Upvotes: 0

mavilein
mavilein

Reputation: 11668

I can't give you a perfect answer, as this seems to be a tricky issue. But there is a project, that aims at integrating Twitter Bootstrap and Ember. So have a look at ember-bootstrap. It is no a complete integration, but it also provides an implementation of NavList. I think it does not yet use the linkTo helper, but i guess it should be relatively easy to do.

If this is no option for you, i only see the option to write an extended version of the linkTo helper in order to wrap the anchor in a li-element, but this not super easy either.

Upvotes: 1

Related Questions