2011-07-17 50 views
3

我剛剛開始使用backbone.js。我在從服務器獲取數據時遇到問題。這是我從服務器獲得的響應。Backbone.js:無法將同一個模型添加到集合中兩次

[{ 
    "list_name":"list1", 
    "list_id":"4", 
    "created":"2011-07-07 21:21:16", 
    "user_id":"123456" 
}, 
{ 
    "list_name":"list2", 
    "list_id":"3", 
    "created":"2011-07-07 21:19:51", 
    "user_key":"678901" 
}] 

這裏是我的javascript代碼...

// Router 
App.Routers.AppRouter = Backbone.Router.extend({ 
    routes: { 
     '': 'index' 
    }, 
    initialize: function() { 
    }, 
    index: function() { 
     var listCollection = new App.Collections.ListCollection(); 
     listCollection.fetch({ 
      success: function() { 
       new App.Views.ListItemView({collection: listCollection}); 
      }, 
      error: function() { 
       alert("controller: error loading lists"); 
      } 
     }); 
    } 
}); 

// Models 
var List = Backbone.Model.extend({ 
    defaults: { 
     name: '', 
     id: '' 
    } 
}); 

App.Collections.ListStore = Backbone.Collection.extend({ 
    model: List, 
    url: '/lists' 
}); 

// Initiate Application 
var App = { 
    Collections: {}, 
    Routers: {}, 
    Views: {}, 
    init: function() { 
     var objAppRouter = new App.Routers.AppRouter(); 
     Backbone.history.start(); 
    } 
}; 

我得到的錯誤在Backbone.js的

if (already) throw new Error(["Can't add the same model to a set twice", already.id]); 
「不能在同一個模型添加到一組兩次」上這條線

我檢查了Backbone.js註釋並發現第一個模型被添加到集合中,但第二個模型給出了這個錯誤。這是爲什麼發生?我應該改變服務器端響應中的某些內容嗎?

回答

8

Listid在其defaults屬性,它是使每個實例在默認情況下具有相同的ID,和骨幹被使用來檢測愚弄。如果您的數據使用list_id作爲ID,則需要通過將idAttribute: 'list_id'放入您的List類定義中來告訴Backbone。另外,我更喜歡不在對象屬性中重複類型信息(並且Backbone.js同意這一點)。具有一致的屬性名稱是主幹所期望的,並且易於使用。因此,不要使用list_idlist_name,只需在所有類上使用idname

+0

救了我很多麻煩 - 謝謝! –

1

使用此修復程序可添加具有相同ID的模型。

增加時,可使用:collection.add(model,{unique: false})

var __hasProp = {}.hasOwnProperty, 
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 

Backbone.Collection = (function(_super) { 

    __extends(Collection, _super); 

    function Collection() { 
     return Collection.__super__.constructor.apply(this, arguments); 
    } 

    Collection.prototype.add = function(models, options) { 
     var i, args, length, model, existing; 
     var at = options && options.at; 
     models = _.isArray(models) ? models.slice() : [models]; 

     // Begin by turning bare objects into model references, and preventing 
     // invalid models from being added. 
     for (i = 0, length = models.length; i < length; i++) { 
      if (models[i] = this._prepareModel(models[i], options)) continue; 
      throw new Error("Can't add an invalid model to a collection"); 
     } 

     for (i = models.length - 1; i >= 0; i--) { 
      model = models[i]; 
      existing = model.id != null && this._byId[model.id]; 

      // If a duplicate is found, splice it out and optionally merge it into 
      // the existing model. 
      if (options && options.unique) { 
       if (existing || this._byCid[model.cid]) { 
        if (options && options.merge && existing) { 
         existing.set(model, options); 
        } 
        models.splice(i, 1); 
        continue; 
       } 
      } 

      // Listen to added models' events, and index models for lookup by 
      // `id` and by `cid`. 
      model.on('all', this._onModelEvent, this); 
      this._byCid[model.cid] = model; 
      if (model.id != null) this._byId[model.id] = model; 
     } 

     // Update `length` and splice in new models. 
     this.length += models.length; 
     args = [at != null ? at : this.models.length, 0]; 
     Array.prototype.push.apply(args, models); 
     Array.prototype.splice.apply(this.models, args); 

     // Sort the collection if appropriate. 
     if (this.comparator && at == null) this.sort({silent: true}); 

     if (options && options.silent) return this; 

     // Trigger `add` events. 
     while (model = models.shift()) { 
      model.trigger('add', model, this, options); 
     } 

     return this; 
    }; 

    return Collection; 

})(Backbone.Collection); 
0

骨幹阻止我們同型號插入到一個集合...... 你可以看到它在Backbone.js的線676線700

如果你真的想在同一模型插入集合,只是刪除代碼中有

if(existing = this.get(model)){//here 
      ... 
    } 
相關問題