0

I have the following mode/collection/view setup in backbone.

var Card = {};  

//card model
Card.Model = Backbone.Model.extend();


//collection
Card.Collection = Backbone.Collection.extend({
    url: '/api/cards',
    model: Card.Model
});

//column view
Card.MainView = Backbone.View.extend({
        className: 'column',
        append: function(model) {
            var view = Card.View.extend({ 
                model : model,
                attributes: { cid : model.cid } 
            });
            var v = new view();
            this.$el.append(v.el);          
        },
        initialize: function() {
            var self = this;
            _.bindAll(this, "sortable");
            this.collection.fetch({ 
                success: function() { 
                    self.render(); 
                } 
            });
        },
        render: function() {
            var self = this;
            for(var i = 0; i < this.columns.length; i++) {
                var col = this.columns[i];
                var column = Card.ColumnView.extend({
                    data: col,
                    cards: self.collection.where({ position : col.position })
                });
                var col = new column();
                this.$el.append(col.el);
            }               
            this.sortable();
        },
        sortable: function() {
            var self = this;
            $(this.el).find('.card-container').sortable({
                connectWith: '.card-container',
                receive: _.bind(function(event, ui) { 
                    var cid = $(ui.item).attr('cid');
                    var card = self.collection.get(cid);
                    //console.log(self.collection.last());
                    console.log('cid', self.collection.get(cid));
                    console.log('index 1', self.collection.at(1));
                    console.log('last', self.collection.last());
                    console.log('collection', self.collection);
                }, this)

            });
        }
}); 

When I try to get a model from the MainView's collection in the sortable function it won't log the model by CID. I get the following output.

cid undefined CardMetaCollection.js:97
index 1 d {collection: d, attributes: Object, _escapedAttributes: Object, cid: "c2", changed: Object…} CardMetaCollection.js:98
last d {collection: d, attributes: Object, _escapedAttributes: Object, cid: "c249", changed: Object…} CardMetaCollection.js:99
collection d {length: 249, models: Array[249], _byId: Object, _byCid: Object, url: "/api/cards"…}

I have tried logging in the success callback for the fetch method but I still get undefined returned... Each model does have its own cid. Any help is much appreciated.

Alex
  • 1,322
  • 1
  • 20
  • 44
  • 1
    Have you ensured that the `cid` attribute is actually being attached to the DOM element in question? Can you make a jsFiddle? – Ben Mar 06 '13 at 17:08

3 Answers3

3

The .get() method accepts either id or cid. The id can be passed directly to the get, but cid has to be passed as an object literal. Actually, you can pass the id in an object literal too and have your code consistent.

var cid = ...;
var card = self.collection.get({ cid: cid });

var id = ...;
var card = self.collection.get({ id: id });

var id = ...;
var card = self.collection.get(id);

You can have a look at the .get() implementation in backbone.js.

UPDATE: The cid alone can be passed to the .get() method in Backbone 0.9.9 or newer (see the implementation in the current 1.3.3).

var cid = ...;
var card = self.collection.get(cid);

In your case, the problem is likely in the attribute "cid" missing on card elements, as Ben writes. You declared an .append() method adding this attribute to new elements, but you call new column() instead of it in the .render() method. It seems, that the column view does not add the attribute, because your logging finds it undefined.

Note: consider using a valid custom HTML attribute name like "data-cid" instead of just "cid", for example.

Community
  • 1
  • 1
Ferdinand Prantl
  • 5,281
  • 34
  • 35
0
  • ensure cid that you are passing into self.collection.get(cid) is a id for any one of the models because the collection.get expects model id as the argument. You might want to log the cid value too for this purpose.
Venkat Kotra
  • 10,413
  • 3
  • 49
  • 53
0

cid use when you pushed differents model to one collection and rest not respond unique id for all request anly individual or maybe REST dont return ID attr or we want to create fake model without rest and push it to collection

 var banned = app.request('rest:banList');
  var whiteIp = app.request("rest:inviteList");
   var whiteGroup = app.request("rest:groupList");
            $.when(banned, whiteIp, whiteGroup).done(function (bannedList,  whiteIpList, whiteGroupList) {
                debugger
                var arr = new Backbone.Collection();
                arr.add(bannedList);
                arr.add(whiteIpList);
                arr.add(whiteGroupList);

            });

define(["app"], function (app) {
    var API = {
        getWho: function (data) {
            var whois = new Backbone.Model();
            whois.url = '/admin/whois';
            whois.cid = 'ban';
            var defer = $.Deferred();

            whois.fetch({
                type: 'GET',
                data: data,
                success: function(data){
                    debugger
                    defer.resolve(data);
                },
                error: function(data){
                    defer.reject(data);
                }
            });
            return defer.promise();
        }
    };

    app.reqres.setHandler("rest:getWho", function (data) {
        return API.getWho(data);
    });
});
zloctb
  • 10,592
  • 8
  • 70
  • 89