【问题标题】:Backbone.js master-detail view, navigation issue (jsfiddle included)Backbone.js 主细节视图,导航问题(包括 jsfiddle)
【发布时间】:2013-03-08 10:07:54
【问题描述】:

我正在努力获得一个使用 Backbone 的简单主从场景。这是jsfiddle,代码如下。

问题 1:如果我将“pushstate”切换为 true,则此导航根本不起作用。我真正想要的是在我的网址中没有哈希/井号。

问题 2:我的用户可能会在 /accommodation/287 之类的 URL 上摇摆不定,而不总是在主页上。你会如何使用路由器来处理这个问题?

非常感谢您的帮助!

var AccommodationItem = Backbone.Model.extend({
    defaults: {
        html: "",
        loaded: false
    },
    urlRoot: "/Home/Accommodation/"
});

var AccommodationItemView = Backbone.View.extend({
    tagName: "li",
    template: _.template("<a href='#accommodation/<%= id %>'><%= description %></a>"),
    render: function () {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

var AccommodationList = Backbone.Collection.extend({
    model: AccommodationItem
});

var DetailView = Backbone.View.extend({
    initialize: function () { },
    render: function () {
        this.$el.html(this.model.get("html"));
    },
    setModel: function (model) {
        this.model = model;
        var $this = this;
        if (!this.model.get("loaded")) {
            /*
            this.model.fetch({ success: function () {
                $this.model.set("loaded", true);
                $this.render();
            }
            });*/
            $this.model.set("html", "<h2>Full item " + this.model.get("id") + "</h2>");
    $this.model.set("loaded", true);
    $this.render();

        } else {
            $this.render();
        }
    }
});

var AccommodationListView = Backbone.View.extend({
    tagName: "ul",
    initialize: function () {
        this.collection.on("reset", this.render, this);
    },
    render: function () {
        this.addAll();
    },
    addOne: function (item) {
        var itemView = new AccommodationItemView({ model: item });
        this.$el.append(itemView.render().el);
    },
    addAll: function () {
        this.collection.forEach(this.addOne, this);
    }
});

var App = new (Backbone.Router.extend({
    routes: {
        "": "index",
        "accommodation/:id": "show"
    },
    initialize: function () {
        this.detailView = new DetailView({ model: new AccommodationItem({ id: 1 }) });
        $("#detail").append(this.detailView.el);
        this.accommodationList = new AccommodationList();
        this.accommodationListView = new AccommodationListView({ collection: this.accommodationList });
        $("#app").append(this.accommodationListView.el);
    },
    start: function () {
        Backbone.history.start({ pushState: false });
    },
    index: function () {
        this.fetchCollections();
    },
    show: function (id) {
        var model = this.accommodationList.get(id);
        this.detailView.setModel(model);
    },
    fetchCollections: function () {
        var items = [{ id: 1, description: "item one" }, { id: 2, description: "item two" }, { id: 3, description: "item three" }];
        this.accommodationList.reset(items);
    }
}));
$(function () {
    App.start();
});

编辑:在下面的评论中,我提到了 Codeschool 主干.js 教程。只想说我现在已经完成了课程的两个部分,它确实涵盖了已接受答案中描述的 AppView 模式。这是一门很棒的课程,我强烈推荐。

【问题讨论】:

    标签: javascript jquery backbone.js


    【解决方案1】:

    您混淆了一些概念。

    这里要解释的太多了,所以我(非常粗略地)整理了你的代码补丁,可以按照你的意愿工作。我建议你把它和你自己的放在一起,看看我做了什么不同的事情。

    http://jsfiddle.net/wtxK8/2

    有几件事,您不应该从路由器中初始化 Backbone.history。你的'init'应该看起来更像这样

          $(function () {
            window.app = new App();
            window.appView = new AppView({el:document});
            Backbone.history.start({ pushState: true });
          });
    

    这是设置一个包含整个页面的“包装”视图。此外,您的路由器中的逻辑太多了。尝试仅将路由器用于路由。经过我的快速重构,您的路由器只包含以下内容:

          var App = Backbone.Router.extend({
            routes: {
              "": "index",
              "accommodation/:id": "show"
            },
            show: function (id) {
              var model = window.appView.accommodationList.get(id);
              window.appView.detailView.setModel(model);
            }
          });
    

    AppView(我现在为您编写的代码可以完成所有初始化工作。

        var AppView = Backbone.View.extend({
            initialize : function(){
              this.detailView = new DetailView({ model: new AccommodationItem({ id: 1 }) });
              $("#detail").append(this.detailView.el);
              this.accommodationList = new AccommodationList();
              this.accommodationListView = new AccommodationListView({ collection: this.accommodationList });
              $("#app").append(this.accommodationListView.el);
              this.fetchCollections();
            },
            fetchCollections: function () {
              var items = [
                { id: 1, description: "item one" },
                { id: 2, description: "item two" },
                { id: 3, description: "item three" }
              ];
              this.accommodationList.reset(items);
            }
          });
    

    即使经过我的重新考虑,它仍然远未达到最佳状态,但我已经提供了这一切来帮助你的学习之旅:)

    然后,我建议您逐步遵循一些在线教程,以便您可以更好地设置应用程序的结构。

    祝你好运,请务必查看http://jsfiddle.net/wtxK8/2 以查看它是否正常工作。

    编辑:我没有回答你的第二个问题。问题 1 有足够的工作让你忙碌。如果以后有更多时间,我会进一步提供帮助。

    【讨论】:

    • 非常感谢!我还在消化那个。我已经完成了许多主干教程(peepcode、tekpub 和 codeschool),它们都是不同的。原始 sn-p 中的代码紧密基于 codeschool.com 的第一个主干课程。我还没有完成第二个,所以可能介绍了您在这里使用的方法。
    • 这绝对是小提琴的正确版本吗?它看起来不像你上面引用的代码。
    • 非常感谢,谢恩。我已将您的版本合并到我的实际应用程序中,它正在发挥作用!关于问题二,我正在使用 asp.net mvc - 所以我很确定我要做的第一件事是将 MVC 路由映射到 /application/id 否则用户将得到 404。不知道如何告诉主干显示详细视图。无论如何,谢谢一百万。
    猜你喜欢
    • 1970-01-01
    • 2018-07-04
    • 2017-07-08
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多