cianmm
cianmm

Reputation: 13

Backbone Collection View is only rendering last object in the collection

I am trying to place the rendered output of a Collection View onto the dom. However, only the last object in the collection is displayed on the page at the end of the process.

I have a event handler set up on the view so that when an item is clicked, it's title is logged out. Whenever I click on this single element that is placed onto the Dom, the title for each of my objects is logged, even though only one is displayed, so each handler is being applied to the final element but is somehow logging out the correct titles.

Does anybody know how I can render out each item in the collection rather than just the final one? Below is a quick tour through my code.

The end goal is to list out the name of each film.

Model

First, define the model - nothing exciting here

var FilmModel = Backbone.Model.extend({});

View

Here is a simplified version of the View I have made for the Film model

var FilmView = Backbone.View.extend({

  // tagName: 'li',

  initialize: function() {
    this.$el = $('#filmContainer');
  },

  events: {
    'click': 'alertName'
  },

  alertName: function(){
    console.log("User click on "+this.model.get('title'));
  },

  template: _.template( $('#filmTemplate').html() ),

  render: function(){
    this.$el.html( this.template( this.model.attributes ) );
    return this;
  }

});

Collection

Again, seems standard.

var FilmList = Backbone.Collection.extend({
  model: FilmModel,
});

Collection View

Adapted from a Codeschool course I took on Backbone

var FilmListView = Backbone.View.extend({
  // tagName: 'ul',

  render: function(){
    this.addAll();
    return this;
  },

  addAll: function(){
    this.$el.empty();
    this.collection.forEach(this.addOne, this);
  },

  addOne: function(film){
    var filmView = new FilmView( { model: film } );
    this.$el.append(filmView.render().el);
    // console.log(this.$el);
  }

});

Go time

var filmList = new FilmList({});

var filmListView = new FilmListView({
  collection: filmList
});


var testFilms = [
  {title: "Neverending Story"},
  {title: "Toy Story 2"}
];

filmList.reset(testFilms);

filmListView.render();

From my understanding of Backbone so far, what this should be doing is appending, using the template specified in FilmView to render each item in the filmList collection into the el in the filmListView.

However, what actually happens is that the final title is always placed on the DOM.

I initially (when this was pulling in from an API) thought that the issue might be similar to this question, however now that I am resetting with my own testFilms, I can be positive that I am not overriding or setting any id attribute that I shouldn't.

Does anybody have any ideas?

Upvotes: 1

Views: 305

Answers (1)

Lbatson
Lbatson

Reputation: 1017

I think it could be that you set the el of FilmView to an id, which should always be unique, however then you loop over the collection and continually reset that el/id with the current model since each FilmView is going to have the same el

Upvotes: 1

Related Questions