【问题标题】:How to create a collection with several model types in backbone.js?如何在backbone.js 中创建具有多种模型类型的集合?
【发布时间】:2011-11-01 02:25:12
【问题描述】:

我正在努力让它发挥作用,但我很难做到。当我检查fetch 上的success 回调时,我的收藏最终为空。在parse 期间,它没有给我任何明确的错误。这是我的代码:

我的收藏:

VOR.Collections.GridItems = Backbone.Collection.extend({
        model : VOR.Models.GridItem,
        url: "assets/data/grid.json",
        parse: function(response){
            var self = this;

            _.each(response, function(griditem){
                switch(griditem.type){
                    case "news":
                        self.add(new VOR.Models.NewsGridItem(griditem));
                        break;
                    default:
                        self.add(new VOR.Models.StandardGridItem(griditem));
                        break;
                }
            });
        }
});

这就是我创建集合的方式:

griditems = new VOR.Collections.GridItems();

griditems.fetch({
    error: function(e) {console.log(e);},
    success: function(msg) {
        console.log(msg)
    });

当我控制台日志msg 我得到: 对象{长度=0,模型=[0],_byId={...},更多...}

我还在集合中记录了 parse 函数,它通过 JSON 文件运行得很好......关于这里可能出现什么问题的任何想法? msg 对象的长度应该是 5..i.e.这就是parse 函数循环和(应该)向集合中添加模型的次数。

【问题讨论】:

    标签: inheritance backbone.js javascript-framework


    【解决方案1】:
    // **parse** converts a response into a list of models to be added to the
    // collection. The default implementation is just to pass it through.
    parse : function(resp) {
      return resp;
    },
    

    这就是文档说你应该在解析中做的事情。无论您返回什么都将被设置为集合起始数组。这是调用它的地方:

      options.success = function(resp) {
        collection[options.add ? 'add' : 'refresh'](collection.parse(resp), options);
        if (success) success(collection, resp);
      }
    

    所以我建议将您的解析更改为:

    return _.map(response, function(griditem){
        switch(griditem.type){
            case "news":
                return new VOR.Models.NewsGridItem(griditem);
                break;
            default:
                return new VOR.Models.StandardGridItem(griditem);
                break;
        }
    });
    

    【讨论】:

      【解决方案2】:

      最好将您的网格项目存储在不同的集合中,并用这样的模型包装它们:

      var model = Backbone.Model.extend({
          url: 'assets/data/grid.json'
          newsItems: Backbone.Collection.extend({
              model: VOR.Models.NewsGridItem
          }),
          standartItems: Backbone.Collection.extend({
              model: VOR.Models.StandardGridItem
          }),
      
          initialize: function() {
              this.newsItems = new this.newsItems();
              this.standartItems = new this.standartItems();
      
              this.newsItems.bind('all', function() {
                  this.trigger.apply(this, arguments);
              }, this)
              this.standartItems.bind('all', function() {
                  this.trigger.apply(this, arguments);
              }, this)
          },
      
          parse: function(request) {
              _.each(response, _.bind(function(griditem) {
                  switch (griditem.type) {
                      case "news":
                          this.newsItems.add(griditem);
                          break;
                      default:
                          this.standartItems.add(griditem);
                          break;
                  }
              }, this));
          }
      })
      
      model.fetch()
      

      【讨论】:

        【解决方案3】:

        处理这个问题的一个好方法是重新定义model 属性,它告诉集合如何将新模型添加到集合中,如这篇帖子中所述:A Backbone.js Collection of multiple Model subclasses(感谢@rulfzid,他回答了我的问题:))

        在您的情况下,您应该能够像这样定义模型属性:

        var VOR.Collections.GridItems = Backbone.Collection.extend({
        
          url: "assets/data/grid.json",
        
          model: function(attrs, options) {
            switch(attrs.type) {
              case "news":
                return new VOR.Models.NewsGridItem(attrs, options);
              default:
                return new VOR.Models.StandardGridItem(attrs, options);
            }
          }
        
        });
        

        【讨论】:

        • 谢谢!这比在parse 中执行此操作要好得多,因为这也适用于引导数据。
        • 这正是我想要的。谢谢!
        • 我认为第一行应该是var VOR.Collections.GridItems = Backbone.Collection.extend({
        猜你喜欢
        • 1970-01-01
        • 2011-10-19
        • 2011-08-29
        • 1970-01-01
        • 2012-08-05
        • 2012-11-18
        • 1970-01-01
        • 2013-05-29
        • 1970-01-01
        相关资源
        最近更新 更多