Reputation: 671
I'm getting started on backbone and am having trouble getting the comparator-driven sort to work. I have a simple Collection that I am using to populate the navigation menu in the page. It's being populated from a MongoDB back end.
window.navItem = Backbone.Model.extend({
initialize: function(){
return {
"title": "no title",
"href": "",
"class": "",
"style": "",
"position": -1,
"showLog": false,
"showUnlog": false
}
},
});
window.navList = Backbone.Collection.extend({
url: "../nav",
initialize: function(){
},
model: navItem,
comparator: function(iNavItem){
return iNavItem.position;
},
});
EDIT to include View code: Just a skeleton that has logic for changing state of the window.loggedIn variable to show/mask the View members based on their showLog/showUnLog properties.
window.navView = Backbone.View.extend({
el: $('#navBar'),
initialize: function(){
var self = this;
this.model.bind("reset", this.render, this);
this.navTemplate = Handlebars.compile($("#navListTemplate").html());
},
events: {
"click #navLogIn" : "navLogIn",
"click #navLogOut" : "navLogOut"
},
render: function() {
this.json = _.where(this.model.toJSON(),
{showUnlog:(!window.loggedIn),
showLog:(window.loggedIn)});
$(this.el).html( this.navTemplate(this.json));
return this;
},
navLogIn: function() {
window.loggedIn = !window.loggedIn;
this.render();
},
navLogOut: function() {
window.loggedIn = !window.loggedIn;
this.render();
}
});
The menu populates and everything seems to work fine except that the collection is not getting sorted by 'position'. I have one menu item that should be in the 2nd slot in the nav menu but last in the collection due to editing in MongoDB. It consistently shows up last in the menu even though it's 'position' value should sort it up to the second place.
The JSON being sent from the server is:
[{
"_id": "50f6fe449f92f91bc1fcbcf6",
"title": "Account",
"href": "",
"htmlId": "",
"class": "nav-header",
"style": "",
"position": 0,
"showLog": true,
"showUnlog": true
},
{
"_id": "50f6fe449f92f91bc1fcbcf7",
"title": "Log In",
"href": "#",
"htmlId": "navLogIn",
"class": "",
"style": "",
"position": 10,
"showLog": false,
"showUnlog": true
},
{
"_id": "50f6fe449f92f91bc1fcbcf8",
"title": "New Account",
"href": "#",
"htmlId": "",
"class": "",
"style": "",
"position": 20,
"showLog": false,
"showUnlog": true
},
snip...
This last item is not being sorted into the proper position and shows up last instead...
{
"_id": "50f6fe449f92f91bc1fcbcf9",
"class": "",
"href": "#",
"htmlId": "navLogOut",
"position": 10,
"showLog": true,
"showUnlog": false,
"style": "",
"title": "Log Out"
}]
Calling theNavList.pluck('position') (theNavList is the instantiated copy of navList) gives me [0, 10, 20, 20, 30, 40, 50, 60, 70, 80, 90, 10].
I've tried manually firing the .sort() function on the collection in Firefox but that fails to correct the Model order in the Collection either in the displayed menu nor in the collection itself.
I feel like I'm missing something very simple here.
Upvotes: 0
Views: 2419
Reputation: 28563
you're just missing the listen.
There's a discussion on this very topic that you might want to look at:
The short of it is that when a user selects 'sort by X', you can:
Another way to handle steps 1 & 2 is to have your own method that calls the Collection's sortBy method and then triggers a custom event that your View can listen to.
But it seems to be the case that clearing and redrawing is the easiest (and maybe even the fastest) way to sort your View's and keep them in sync with your Collection's sort order.
Upvotes: 1