15

我正在使用 Backbone.js 学习 JavaScript MVC 应用程序开发,并且在视图中呈现模型集合时遇到问题。这是我想要做的:

  • 页面完成加载后,从服务器检索数据作为模型集合

  • 在视图中渲染它们

这就是我想做的,这就是我到目前为止所做的:

$(function(){

    "use strict";

    var PostModel = Backbone.Model.extend({});

    var PostCollection = Backbone.Collection.extend({
        model: PostModel,
        url: 'post_action.php'
    });

    var PostView = Backbone.View.extend({
        el: "#posts-editor",        

        initialize: function(){
            this.template = _.template($("#ptpl").html());
            this.collection.fetch({data:{fetch:true, type:"post", page:1}});
            this.collection.bind('reset', this.render, this);
        },

        render: function(){
            var renderedContent = this.collection.toJSON();
            console.log(renderedContent);
            $(this.el).html(renderedContent);
            return this;
        }
    });

    var postList = new PostCollection();
    postList.reset();
    var postView = new PostView({
        collection: postList
    });

});

问题

据我所知,Chrome 正在记录来自服务器的响应,并且它是我想要的 JSON 格式。但在我看来,它并没有呈现出来。控制台中没有明显的错误。

服务器有一个处理程序,它接受 GET 参数并回显一些 JSON: http://localhost/blog/post_action.php?fetch=true&type=post&page=1

[
   {
      "username":"admin",
      "id":"2",
      "title":"Second",
      "commentable":"0",
      "body":"This is the second post."
   },
   {
      "username":"admin",
      "id":"1",
      "title":"Welcome!",
      "commentable":"1",
      "body":"Hello there! welcome to my blog."
   }
]
4

4 回答 4

11

您的代码有 2 个潜在问题。

  1. 事件侦听器回调应在调用之前collection.fetch()注册。否则,您可能会错过第一个reset事件,因为它可能在侦听器注册之前触发。

  2. reset事件不足以确保每次更新集合时视图都会重新呈现。

另外,请注意,使用object.listenTo()表单绑定事件是一种很好的做法,因为它可以确保在关闭视图时正确取消注册。否则,您最终可能会遇到所谓的骨干僵尸。这是一个解决方案。

this.listenTo( this.collection, 'reset add change remove', this.render, this );
this.collection.fetch({ data: { fetch:true, type:"post", page:1 } });

请注意如何通过用空格分隔来自同一对象的多个事件来注册它们。

于 2013-07-12T20:53:05.810 回答
2

改变

this.collection.bind('reset', this.render, this);

this.collection.bind('sync', this.render, this);

问题是您一开始只执行一次重置。那时你没有任何东西可以渲染。下一次,当您获取集合时,不会触发重置事件,因为您获取集合时没有选项 {reset: true}。

于 2013-07-11T22:19:12.043 回答
1

更改此行

this.collection.bind('reset', this.render, this);

this.listenTo(this.collection, 'reset', this.render);
于 2013-07-11T23:38:07.200 回答
0

获取您的收藏时,默认情况下不再触发重置事件。(我相信从 1.0 版开始)为了让 Backbone 在获取集合时触发重置事件,您现在必须像这样调用 fetch 方法:

this.collection.fetch({reset: true});
于 2014-11-02T18:54:26.113 回答