Reputation: 254
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:
Clearly I'm making a lot of fundamental errors here. Could someone please put me right.
Upvotes: 3
Views: 2667
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
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
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