【问题标题】:Backbone toJSON not rending骨干 toJSON 不呈现
【发布时间】:2014-03-03 18:18:24
【问题描述】:

我是 Backbone.js 的一个完整的 n00b,并且只使用了几天。我正在尝试获取 JSON 数据来填充模型,在这种情况下,我需要生成两个模型。这是我一直在使用的示例 JSON:

JSON

{
"status": "200",
"total": "2",
    "items":
    [{
        "id": "1",
        "name": "Here is another name",
        "label": "Label for test",
        "description": "A description for more information.",
        "dataAdded": "123456789",
        "lastModified": "987654321"
    },
    {
        "id": "2",
        "name": "Name of item",
        "label": "Test Label",
        "description": "This is just a long description.",
        "dataAdded": "147258369",
        "lastModified": "963852741"
    }]
}

主干 JS

// MODEL
var Service = Backbone.Model.extend({
defaults: {
    id: '',
    name: '',
    label: '',
    description: '',
    dateAdded: '',
    dateModified: ''
}
});
var service = new Service();

// COLLECTION
var ServiceList = Backbone.Collection.extend({
    model: Service,
    url: "./api/service.php",
    parse: function(response) {
        return response.items;
    }
});
//
var serviceList = new ServiceList();
var jqXHR = serviceList.fetch({
    success: function() {
        console.log("Working!");
                console.log(serviceList.length);
    },
    error: function() {
        console.log("Failed to fetch!");
    }
});


// VIEW for each Model
var ServiceView = Backbone.View.extend({
    el: $('.widget-content'),
    tagName: 'div',
    template: _.template($('#service-template').html()),
    initialize: function() {
        this.collection.bind("reset", this.render, this);
    },
    render: function() {
        console.log(this.collection);
        this.$el.html('');
        var self = this;
        this.collection.each(function(model) {
            self.$el.append(self.template(model.toJSON()));
        });
        return this;
    }
});
//
var serviceView = new ServiceView({
    collection: serviceList
});
console.log(serviceView.render().el);

html

<div class="widget-content">
    <!-- Template -->
    <script type="text/template" id="service-template">
        <div><%= name %></div>
    </script>
</div>

当我在控制台记录 serviceList.length 时,我得到的值为 2,因此我相信 JSON 对象已成功获取。我也得到了“工作!”对成功的回应也是如此。但是,在视图中,我显示的是一个空对象,这给了我一个空模型。

我仍在尝试了解执行此操作的最佳方法。也许我应该为“项目”使用集合,然后为每个模型数据映射集合?我究竟做错了什么?非常感谢任何建议或帮助。

【问题讨论】:

    标签: json backbone.js model render


    【解决方案1】:

    我可以看到两个问题。首先,您要删除serviceList.reset(list)。您的收藏应通过调用fetch 自动填充。 (无论如何fetch的返回值不是来自服务器的数据结果,而是“jqXHR”对象)。

    var serviceList = new ServiceList();
    var jqXHR = serviceList.fetch({
        success: function(collection, response) {
            console.log("Working!");
    
            // this is the asynchronous callback, where "serviceList" should have data
            console.log(serviceList.length);
            console.log("Collection populated: " + JSON.stringify(collection.toJSON()));
        },
        error: function() {
            console.log("Failed to fetch!");
        }
    });
    // here, "serviceList" will not be populated yet
    

    其次,您可能希望将serviceList 实例作为其“集合”传递到视图中。实际上,您将一个空模型实例传递到视图中。

    var serviceView = new ServiceView({
        collection: serviceList
    });
    

    对于视图,使用集合进行渲染:

    var ServiceView = Backbone.View.extend({
        // ...
    
        initialize: function() {
            // render when the collection is reset
            this.collection.bind("reset", this.render, this);
        },
        render: function() {
            console.log("Collection rendering: " + JSON.stringify(this.collection.toJSON()));
    
            // start by clearing the view
            this.$el.html('');            
    
            // loop through the collection and render each model
            var self = this;
            this.collection.each(function(model) {
                self.$el.append(self.template(model.toJSON()));
            });
            return this;
        }
    });
    

    Here's Fiddle 演示。

    【讨论】:

    • 感谢您对 fetch 的理解。我看到 JSFiddle 确实有效,但是在复制时我仍然得到一个空模型。我很困惑为什么您建议删除 serviceList 重置,但将其添加到 JSFiddle 中?
    • @user3362859 我将它添加到 Fiddle 中只是作为一个模拟 - 通常您在手头已有数据时使用 collection.reset,然后使用 collection.fetch 向服务器发送请求。不过,您不需要同时使用两者...
    • 这是有道理的。我看到 jqXHR 有我们获取的存储数据,但我没有看到它传递到集合中。这可能是模型仍然为空的原因。我需要将 jqXHR 传递给集合吗?
    • 我更新了帖子以显示我在您的修订中拥有的代码。你能看出是什么导致了空模型吗?
    • @user3362859 是的——您的示例中的“服务”对象只是一个空模型。它与提取到“serviceList”集合中的数据完全没有联系。
    【解决方案2】:

    调用serviceList.fetch 是异步进行的,所以当你尝试console.log(serviceList.length); 时,服务器还没有发送它的响应,这就是你得到值1 的原因,试试这个:

    var list = serviceList.fetch({
        success: function() {
            console.log(serviceList.length);
            console.log("Working!");
        },
        error: function() {
            console.log("Failed to fetch!");
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多