Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pull any class by its cid in Backbone?

Tags:

backbone.js

In using Backbone.js, I've noticed that both views and models are given cids. I understand that if these classes are part of a collection, I can pull any of them by collection.getByCid. Is it at all possible to pull any class, outside of a collection, given its cid, using Backbone?

For example, if I have MyObject.Views.Tree = Backbone.View.extend({ });, I can create a new Tree view from var tree = new MyObject.Views.Tree();. Calling tree.cid returns a specific cid--something like view231. Is there any way to reference my tree view given only its cid? A global Backbone.getByCid method, perhaps?

like image 551
Ian Hunter Avatar asked Aug 26 '11 15:08

Ian Hunter


2 Answers

ExtJS spoiled me and I felt the need to recreate something similar for Backbone. Maybe this will help you out too? I haven't tested it too much, but it's a very simple change. Just be careful of creating lots of things and not removing them, or you'll have a bunch of registered objects eating up memory.

Backbone.View.Registry = {
    items: {},
    register: function (id, object) {
        this.items[id] = object;
    },
    lookup: function (id) {
        return this.items[id] || null;
    },
    remove: function (id) {
        delete this.items[id];
    }
}

Backbone.RegisteredView = Backbone.View.extend({
    initialize: function () {
        Backbone.View.prototype.initialize.apply(this);
        this.cid = this.options.id || this.cid; //just in case you want to assign a unique ID and lookup from that.
        Backbone.View.Registry.register(this.cid, this);
    },
    remove: function () {
        Backbone.View.prototype.remove.apply(this);
        Backbone.View.Registry.remove(this.cid);
                    return this;
    }
});

test = Backbone.RegisteredView.extend({
    intialize: function () {
        return $("<div></div>"); //Just return something for this example
    }
});

div1 = new test({id: 'header_pane'});

div2 = new test();

console.log(Backbone.View.Registry.items); //Will have the header_pane and a cid based obj in it

    ref = Backbone.View.Registry.lookup('header_pane');
    console.log(ref); //Will be the header_pane object

div1.remove();

console.log(Backbone.View.Registry.items); //Will only have the cid based object in it
like image 56
Stephen Avatar answered Oct 06 '22 23:10

Stephen


No.

I think you have a slight misunderstanding of the backbone programming model, as well as JavaScript in general. Backbone doesn't keep track of what you create; it only helps you create objects with specific prototypes (Models, Collections, etc.). It doesn't care at all what you do with them. The CID is just a convenience method you can use for indexing and cross-referencing, but you have to write the indices and cross-references yourself.

So if you create an object and don't keep a reference to it somewhere (in a collection, in your router, in another object), it becomes inaccessible and the JavaScript VM will eventually garbage collect it.

like image 43
Elf Sternberg Avatar answered Oct 06 '22 22:10

Elf Sternberg