populating menus from multiple collections

I'm new to backbone.js and express and I have been adapting Christophe Coenraets Wine Cellar REST API example application for my own project.

I am building a form that has several menus needing to be populated from multiple unrelated collections in mongodb.

I am able to populate one menu with one collection, but I have no idea how to get more than one collection to my form View.

Here are the files I am using to populate one menu. How do I expand this to populate two menus?

I suppose I could make a new View for every menu I want to populate - but that seems like overkill.

Can I combine two mongodb find() collections into one object, and list them separately on a page? If so, how?

thanks in advance!

/routes/modules.js contains:

exports.findAllModules = function(req, res) {

db.collection('modules', function(err, collection) {

    collection.find().toArray(function(err, items) {

        res.send(items);

    });

}); 

};

/server.js contains:

app.get('/modules', module.findAllModules);

/public/js/main.js contains:

routes: {

"modules" : "list" }

...

list: function(page) {

    var p = page ? parseInt(page, 10) : 1;

    var moduleList = new ModuleCollection();

    moduleList.fetch({success: function(){

        console.log('in list function');

        $("#content").html(new ModuleListView({model: moduleList, page: p}).el);

    }});

    this.headerView.selectMenuItem('home-menu');

},

...

utils.loadTemplate([

'ModuleListItemView' ], function() {

app = new AppRouter();

Backbone.history.start(); });

/public/models/models.js contains:

window.Module = Backbone.Model.extend({

urlRoot: "/modules",

idAttribute: "_id",

initialize: function () {
    this.validators = {};

    this.validators.name = function (value) {
        return value.length > 0 ? {isValid: true} : {isValid: false, message: "You must enter a name"};
    };

validateItem: function (key) {
    return (this.validators[key]) ? this.validators[key](this.get(key)) : {isValid: true};
},
validateAll: function () {
    var messages = {};

    for (var key in this.validators) {
        if(this.validators.hasOwnProperty(key)) {
            var check = this.validators[key](this.get(key));
            if (check.isValid === false) {
                messages[key] = check.message;
            }
        }
    }
    return _.size(messages) > 0 ? {isValid: false, messages: messages} : {isValid: true};
},

defaults: {
    _id: null,
    name: ""
} });

window.ModuleCollection = Backbone.Collection.extend({

model: Module,

url: "/modules"

});

/public/js/views/modulelist.js contains:

window.ModuleListView = Backbone.View.extend({

initialize: function () {
    this.render();
},

render: function () {
    var modules = this.model.models;

    $(this.el).html('<ul class="thumbnails"></ul>');

    for (var i = 0; i < modules.length; i++) {
        $('.thumbnails', this.el).append(new ModuleListItemView({model: modules[i]}).render().el);
    }
    return this;
} });

window.ModuleListItemView = Backbone.View.extend({

tagName: "li",

initialize: function () {

    this.model.bind("change", this.render, this);

    this.model.bind("destroy", this.close, this);

},

render: function () {

    $(this.el).html(this.template(this.model.toJSON()));

    return this;

} });

/public/tpl/ModuleListView.html contains:

Not entirely sure how your code works, but here are a few backbone tips.

If you wanna build a menu from a collection don't pass the collection as a model.

Instead of:

    $("#content").html(new ModuleListView({model: moduleList, page: p}).el);

Use:

    $("#content").empty().append(new ModuleListView({collection: moduleList, page: p}).el);

Instead of:

render: function () {
    var modules = this.model.models;

    $(this.el).html('<ul class="thumbnails"></ul>');

    for (var i = 0; i < modules.length; i++) {
        $('.thumbnails', this.el).append(new ModuleListItemView({model: modules[i]}).render().el);
    }
    return this;
}

Use:

render: function () {
    this.$el.html('<ul class="thumbnails">');

    this.collection.each(function(model) {
        this.$('.thumbnails').append(new ModuleListItemView({model: model}).render().el);
    }, this);

    return this;
}

If you have no need in updating or deleting your models, it's enough to add the url path /modules only to the collection, for reading the initial modules.