【问题标题】:Backbone.js: Fetch a collection of models and render themBackbone.js:获取模型集合并渲染它们
【发布时间】:2013-07-10 08:58:35
【问题描述】:

我正在学习使用 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."
   }
]

【问题讨论】:

    标签: javascript json backbone.js backbone-views


    【解决方案1】:

    改变

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

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

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

    【讨论】:

    • 我这样做了,但现在我在控制台中得到了Uncaught Error: A "url" property or function must be specified,但我将url 属性设置为post_action.php
    • 我不知道它是如何被这个改变破坏的。也许您应该尝试删除“使用严格”;目前?好像是图书馆里面的东西。只需尝试将 urlRoot: 'post_action.php' 添加到您的模型中。
    【解决方案2】:

    改变这一行

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

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

    【讨论】:

    • 不,抓取后他不会收到reset事件。顺便说一句,您的解决方案的唯一区别是上下文和解除绑定。为什么你认为它应该有所帮助?
    • 您使用的是哪个版本?我正在使用 0.9.2 并且在 listenTo 上出现错误。
    【解决方案3】:

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

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

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

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

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

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

    【讨论】:

    • 唯一有效的解决方案!谢谢@mor
    • 你能解释一下onFetch回调是什么意思,它需要“在调用collection.fetch()之前注册。否则,你可能会错过第一个reset事件”?也就是说,我在原始代码或您的示例中没有看到onFetch 回调函数。
    • @Pea 你是对的,这令人困惑。我指的是事件监听器。我会编辑。
    • @mor 感谢您花时间解释和更新。很有帮助。
    【解决方案4】:

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

    this.collection.fetch({reset: true});
    

    【讨论】:

      猜你喜欢
      • 2016-06-09
      • 2011-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      • 2011-11-30
      • 2011-10-31
      相关资源
      最近更新 更多