I was trying to dynamically change the url inside the router but couldn't manage to do it, it keeps returning to the base Collection URL. Here i posted the code with the 3 different collections which apart from pointing to three different urls they do exactly the same.
I have only one model
and three collections
that depend on that model and they even render the same view. How can i dynamically change the url
so i can create only one Collection
and one Model
? Is it best pracitce for a case like this?
// MODELS & COLLECTIONS
window.Post = Backbone.Model.extend({
urlRoot: function() {
return 'http://localhost:5000/json/guides/:id'
}
})
App.Collections.RecentPosts = Backbone.Collection.extend({
model: Post,
url:'http://localhost:5000/json/posts/recent',
})
App.Collections.PopularPosts = Backbone.Collection.extend({
model: Post,
url:'http://localhost:5000/json/posts/popular',
})
App.Collections.FeaturedPosts = Backbone.Collection.extend({
model: Post,
url:'http://localhost:5000/json/posts/featured',
})
// CONTROLLER
App.Controllers.Documents = Backbone.Router.extend({
routes:{
"recent" : "recent",
"popular" : "popular",
"featured" : "featured",
},
recent: function(){
//.... same as featured ?
},
popular: function(){
//.... same as featured ?
},
featured: function(){
$("#browser").empty();
var collection = new App.Collections.Posts();
collection.fetch({
success: function(col,posts){
new App.Views.GuideView({collection: posts});
},
error: function(error){
console.log(error)
}
})
}
});
There are numerous different ways of doing this. Here's what's probably going to be 'best practice'.
App.Controllers.Documents = Backbone.Router.extend({
routes:{
"recent" : "recent",
"popular" : "popular",
"featured" : "featured",
},
initialize: function () {
this.collection = new App.Collections.Posts();
},
_showPage: function (config) {
$("#browser").empty();
this.collection.fetch({
url: config.url,
success: function(col,posts){
new App.Views.GuideView({collection: posts});
},
error: function(error){
console.log(error)
}
});
},
recent: function(){
this._showPage({url:'http://localhost:5000/json/posts/recent'});
},
popular: function(){
this._showPage({url:'http://localhost:5000/json/posts/popular'});
},
featured: function(){
this._showPage({url:'http://localhost:5000/json/posts/featured'});
}
});
Since I really don't know how complicated your page is going to get, this is probably the best I can do without more information. But, the idea is that "this.collection" is set on the routers initialization.. so you can keep reusing it. The _showPage method does whatever basic tasks you need done to show the page, and the methods called by the routes use it to do whatever basic stuff needs done before going into detail. The url passed into the config would simply tell the collection where to get its information from - I'm assuming that all of your data has the same format and 'is the same thing'.. just different filters.
You can probably do a similar thing with App.Views.GuideView
:
App.Controllers.Documents = Backbone.Router.extend({
routes:{
"recent" : "recent",
"popular" : "popular",
"featured" : "featured",
},
initialize: function () {
this.collection = new App.Collections.Posts();
this.view = new App.Views.GuideView({collection: this.collection});
},
_showPage: function (config) {
$("#browser").empty();
this.collection.fetch({
url: config.url,
success: _.bind(function(col,posts){
this.view.render();
}, this),
error: function(error){
console.log(error)
}
});
},
recent: function(){
this._showPage({url:'http://localhost:5000/json/posts/recent'});
},
popular: function(){
this._showPage({url:'http://localhost:5000/json/posts/popular'});
},
featured: function(){
this._showPage({url:'http://localhost:5000/json/posts/featured'});
}
});
The 'render' would just rebuild the view, and since you've already got the collection referenced in the view as "this.options.collection" (or you could add an 'initialize' to the view and set this.collection to be this.options.collection). When the collection gets updated, all of that information is by reference in the view.. so no need to reset it.
I think the best pratice would be to have 3 collections, each with it's on URL and properties.
This makes the code easier to maintain as you can assign different events and listeners to them in a separate file instead of having a "God Collection" that have all the logic inside it.
Of course you can still be DRY and keep a helper object or a parent collection with code that is commmon to all those collections.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With