4

I'm new to Backbone JS and have been following Christopher Coenraets Wine Cellar tutorial.

It all works fine and dandy but I don't understand how he is using this.model.models to access a collection rather than this.collection. Furthermore when I try changing the code to the latter it appears that this.collection is undefined.

window.WineListView = Backbone.View.extend({

    tagName:'ul',

    initialize:function () {
        this.model.bind("reset", this.render, this);
    },

    render:function (eventName) {
        _.each(this.model.models, function (wine) {
            $(this.el).append(new WineListItemView({model:wine}).render().el);
        }, this);
        return this;
    }

});
nikoshr
  • 32,926
  • 33
  • 91
  • 105
HankHendrix
  • 295
  • 2
  • 9
  • 2
    `models` is a member of a Collection object. The name that a Collection is assigned to (`model` vs `collection`) is just like any other variable name and has no connection to the type of object contained. – Matt Whipple Jan 04 '13 at 12:14

1 Answers1

6

Two things lead to your dismay:

  • You can inject a collection in a view however you want. The usual way is to pass a collection attribute, but here it is passed as a model in the router:

    this.wineList = new WineCollection();
    this.wineListView = new WineListView({model:this.wineList});
    
  • collection.models holds the raw array of models in a collection

    models collection.models
    Raw access to the JavaScript array of models inside of the collection. Usually you'll want to use get, at, or the Underscore methods to access model objects, but occasionally a direct reference to the array is desired.

If you want to use this.collection in your view, you should modify the router to

this.wineList = new WineCollection();
this.wineListView = new WineListView({collection: this.wineList});

and you could then use it as

window.WineListView = Backbone.View.extend({
    tagName: 'ul',

    initialize: function () {
        this.collection.bind("reset", this.render, this);
    },

    render: function (eventName) {
        // Backbone proxies Underscore methods on collections
        // _.each(this.collection.models, function (wine) {

        this.collection.each(function (wine) {
            $(this.el).append(new WineListItemView({model: wine}).render().el);
        }, this);

        return this;
    }
});
nikoshr
  • 32,926
  • 33
  • 91
  • 105