Search code examples
collectionsbackbone.jsviewmodels

Best way to connect models to collections with backbone js


I'm having some problems with linking my models - which have their own views into a collection. I don't know whether I am doing this the correct way or not. I don't know if I need a view for the collection as well.

Here is the barebones code for my app.

var Model = Backbone.Model.extend ({
initialize : function () {
    new ModelView({model:this});
}
});

var ModelCollection = Backbone.Collection.extend({
initialize : function () {
    console.log('collected');
    this.on("add",function(){
        console.log('added model');
    });
},
model: Model
}); 

var Models = new ModelCollection;

var ModelView = Backbone.View.extend({
initialize : function () {
    console.log('view is loaded');
    this.render();
    this.model.on('change', this.render, this);
},
el: $('#menu'),
render : function () {
    var data = this.model.toJSON();
    var template = Handlebars.compile($("#menu-template").html());
    $(this.el).html(template(data));
    return this; 
},
});

var ModelCollectionView = Backbone.View.extend({
initialize : function () {
    console.log('Collection view created');
    Models.bind('add', this.addOne, this);
    Models.bind('reset', this.addAll, this);
    Models.bind('all', this.render, this);
},

addOne : function (model) {
    console.log('working');
    var view = new ModelView({model: model});
}
});

var ModelCollection = new ModelCollectionView;

I don't know if i'm missing something here or whether I need this bit of code

var model = new Model();
Models.push(model);

I just can't find a basic example of this anywhere. Thanks in advance.


Solution

  • Based on the code you show, I would suggest you go through a tutorial on backbone.js (Google is a good place to start). There is a lot of them out there, and it will help you understand the relations between views, models and collections.

    That being said, it seems strange to have a model which only creates a new view of the model. The whole point of a model is that is should contain data, which is again shown in the view. Look at how this example is distributing it:

    //Some doctors in an array, just mockupdata to create models from
    var someDoctors = [
        { name: "SomeName1" type: "Surgeon" },
        { name: "SomeName2" type: "Surgeon" },
        { name: "SomeName3" type: "Surgeon" },
        { name: "SomeName4" type: "Surgeon" }
    ];
    
    //define product model
    var Doctor = Backbone.Model.extend({
        defaults: {
            favoriteTool: "Stethoscope"
        }
    });
    
    //define a hospital collection of doctors
    var Hospital = Backbone.Collection.extend({
        model: Doctor
    });
    
    //define individual doctor view which renders a template based on data from the model
    var doctorView = Backbone.View.extend({
        tagName: "li",
        className: "doctor-container",
        template: $("#doctorTemplate").html(),
    
        render: function () {
            var tmpl = _.template(this.template);
            $(this.el).html(tmpl(this.model.toJSON()));
            return this;
        }
    });
    
    //define the hospital view
    var hosptialView = Backbone.View.extend({
        el: $("#doctors"),
    
        initialize: function () {
            this.collection = new Hosptial(someDoctors);
            this.render();
        },
    
        // go through all models in the hospital and calls renderDoctor for each model
        render: function () {
            var that = this;
            _.each(this.collection.models, function (item) {
                that.renderDoctor(item);
            }, this);
        },
    
        //create a view for the item (doctormodel) and appends it to this views el.
        renderDoctor: function (item) {
            var doctorView = new DoctorView({
                model: item
            });
            this.$el.append(doctorView.render().el);
        }
    });
    
    //create instance of hospital view
    var hosptial = new hosptialView();
    

    As you can see, the Collection is connected to doctor, the collection view creates a doctorview for each doctor and appends it to it self.

    If you want to listen for adds to the collection, do it in the collectionview initialize, and call renderDoctor:

    Hospital.bind('add', this.renderDoctor, this);