我试图动态更改路由器内部的url但无法设法执行此操作,它会一直返回到基本的Collection URL。在这里,我发布了代码与3个不同的集合,除了指向三个不同的网址,他们完全相同。
我只有一个model
和三个collections
依赖于该模型,他们甚至渲染相同的视图。如何动态更改url
,以便我只能创建一个Collection
和一个Model
?对于像这样的案件,这是最好的实践吗?
// 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)
}
})
}
});
答案 0 :(得分:6)
有很多不同的方法可以做到这一点。这可能是“最佳实践”。
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'});
}
});
因为我真的不知道你的页面会有多复杂,所以如果没有更多的信息,这可能是我能做的最好的事情。但是,我们的想法是在路由器初始化时设置“this.collection”。所以你可以继续重用它。 _showPage方法执行显示页面所需的任何基本任务,并且路由调用的方法使用它来执行任何基本的东西需要完成后再详细说明。传递给配置的网址只会告诉集合从何处获取其信息 - 我假设您的所有数据都具有相同的格式并且“是相同的东西”......只是不同的过滤器。
您可以使用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'});
}
});
'render'只会重建视图,因为你已经将视图中引用的集合称为“this.options.collection”(或者你可以在视图中添加'initialize'并设置它。集合是this.options.collection)。当集合更新时,所有这些信息都在视图中引用..所以不需要重置它。
答案 1 :(得分:1)
我认为最好的实践是拥有3个集合,每个集合都有URL和属性。
这使得代码更易于维护,因为您可以在单独的文件中为它们分配不同的事件和侦听器,而不是拥有其中包含所有逻辑的“God Collection”。
当然,您仍然可以使用DRY并使用通用于所有这些集合的代码来保留辅助对象或父集合。