简体   繁体   中英

Fetching collection with backbone.js but id for each model is not set

In short, I'm fetching a collection but afterwards I'm unable to get a specific entity from the collection using either its id or cid .

For this problem, consider my two REST endpoints /sites and /sites/some-site-id/entities Both sites and entities are collections. Here are my models/collections:

Models / collections

var ROOT = 'http://localhost:5000';

Entity = Backbone.Model.extend({
    idAttribute: "_id",
    defaults: {
        xpos: 10,
        ypos: 10,
        site: "default"
    }
});

Entities = Backbone.Collection.extend({
    model: Entity,
    ownUrl: '/entities',
    site: {},
    url: function() {
        return ROOT + "/sites/" + (this.site? this.site : 'null') + this.ownUrl;
    },
    initialize: function(models, options) {
        if(!options.site) throw new Error("No site associated with entities");
        if(!options.site.get("_id")) throw new Error("Associated site has no _id");

        this.site = options.site.get("_id");
    }
});

Site = Backbone.Model.extend({
    idAttribute: "_id",
    defaults: {
        name: "default",
        description: "My site"
    }
});

Sites = Backbone.Collection.extend({
    model: Site,
    url: ROOT + "/sites"
});

My problem is that when I'm fetching the entities for a site, I cannot lookup a certain entity from the collection using the get method on collection. I simply get undefined returned.

This is how I test it (entities.fetch will get 4 entities):

Test code

var site1 = new Site({id : "52813a2888c84c9953000001"});
sites.add(site1);
site1.fetch({success: function(model, response, options) {
    entities = new Entities([], {site: site1});
    entities.fetch({success: function(model, response, options) {
        entities.each(function (entity) {
            console.log("entity.get(\"_id\") = " + entity.get("_id"));
            console.log("entity.id = " + entity.id);
            console.log("Looking up entity using id (" + entity.get("_id") + "): " + entities.get(entity.get("_id")));
            console.log("Looking up entity using cid (" + entity.cid + "): " + entities.get(entity.cid));
            console.log("");
        });
    }});
}});

When I run this, I get:

Test result

entity.id = undefined
entity.get("_id") = 528146ade34176b255000003
Looking up entity using id (528146ade34176b255000003): undefined 
Looking up entity using cid (c1): undefined

entity.id = undefined
entity.get("_id") = 528146ade34176b255000002
Looking up entity using id (528146ade34176b255000002): undefined
Looking up entity using cid (c2): undefined

entity.id = undefined
entity.get("_id") = 528146ade34176b255000001
Looking up entity using id (528146ade34176b255000001): undefined
Looking up entity using cid (c3): undefined

entity.id = undefined
entity.get("_id") = 528146ade34176b255000004
Looking up entity using id (528146ade34176b255000004): undefined
Looking up entity using cid (c4): undefined 

What I would expect is for the collection to return the specific entity. Does it have something to do with my special idAttribute "_id" (for compliance with mongodb)?

EDIT

Apparently it seems to have something to do with my idAttribute. Because if I add an "id" field to every entity returned, I can lookup entities using its id. Like so on server side:

function getEntitiesInSite(siteId, fun) {
    db.siteentities.find({site: mongojs.ObjectId(siteId)}, function(err, entities) {
        entities.forEach(function (entity) {
            entity.id = entity._id;
        });
        fun(err, entities);
    });
}

This isn't exactly what I wanted and I can imagine that I would run into other problems in the future with inconsistent id's (having both id and _id fields).

the root of problems is your models' id attribute is not set.

id is only checked and set to your idAttribute when the model's set method is called.

When you fetch from collection successfully, there is no call to set function of the model. So id is undefined for models.

you need to trigger set event in each of your entity model in order for this to work.

I found out I was running an old version of backbone.js. Which obviously couldn't be noticed by anyone else, since I didn't add that information to the question.

With backbone.js 1.1.0 and underscore 1.4.4 everything works just fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM