5

我试图动态更改路由器内部的 url,但无法做到,它一直返回到基本 Collection URL。在这里,我发布了包含 3 个不同集合的代码,这些集合除了指向三个不同的 url,它们的功能完全相同。我只有一个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)
                                }
                        })
            }
    });
4

2 回答 2

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 方法执行显示页面所需的任何基本任务,并且路由调用的方法使用它来执行在详细介绍之前需要完成的任何基本工作。传递到配置中的 url 只会告诉集合从哪里获取其信息 - 我假设您的所有数据都具有相同的格式并且“是相同的东西”......只是不同的过滤器。

您可能可以使用以下方法做类似的事情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'});
        }
});

“渲染”只会重建视图,并且由于您已经在视图中将集合引用为“this.options.collection”(或者您可以向视图添加“初始化”并将 this.collection 设置为this.options.collection)。当集合更新时,所有这些信息都在视图中通过引用..所以不需要重置它。

于 2012-10-02T18:59:40.030 回答
1

我认为最好的做法是拥有 3 个集合,每个集合都在 URL 和属性上。

这使得代码更易于维护,因为您可以在单独的文件中为它们分配不同的事件和侦听器,而不是拥有一个包含所有逻辑的“上帝集合”。

当然,您仍然可以保持 DRY 并使用所有这些集合共有的代码保留一个辅助对象或父集合。

于 2012-10-02T18:58:05.993 回答