2

我正在努力获得一个使用 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 模式。这是一门很棒的课程,我强烈推荐它。

4

1 回答 1

3

您混淆了一些概念。

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

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 有足够的工作让你忙碌。如果以后有更多时间,我会进一步提供帮助。

于 2013-03-08T15:14:31.500 回答