Question

Being new to Backbone.js, I try to develop a SPA following, amongst others, Addy Osmani's "Developing Backbone.js Applications". It's exercise 2 (http://addyosmani.github.io/backbone-fundamentals/#exercise-2-book-library---your-first-restful-backbone.js-app) shows, how to use a collection view to render inner model views from each of the collections objects. However, the collection view in this example does not come with its own html markup. Thus, the collection's models are associated with the collection view's DOM element (here: '#books'). I want to use an own template to first render the html elements of my collection view, say, a simple div with id="the-plan". Problem is, "#the.plan" is not recognized from the inner model views as element attribute. Hence, the inner views are not rendered at all. There is no error message and all console.logs are working. Code looks something like this:

app.PlanItemView = Backbone.View.extend({
  className: "plan-item",
  template: _.template($("#plan-item-view-template").html()),

  render: function(){
    console.log("Rendering plan item view...");
    this.$el.append(this.template(this.model.toJSON()));
    return this;
  }
});

app.PlanView = Backbone.View.extend({
  el: ".main-panel",
  id: "#the-plan",
  template: _.template($("#plan-view-template").html()),

  initialize: function(initialPlanItems){
    console.log("Plan View initialized... Selector: " + this.id);
    console.log("Incoming initial plan item data: " + _.first(_.values(_.first(initialPlanItems))));
    this.collection = new app.MealPlan(initialPlanItems);
    this.render();
  },

  // render plan by rendering each item in its collection
  render: function() {

    this.$el.append(this.template({
      "myPlan": this.collection.each(function(item){
      this.renderPlanItem(item);
    }, this)
    }));

    return this;
  },

  // render a plan item by creating a PlanItemView and appending the
  // element it renders to the plan's id-element ('#the-plan')
  renderDish: function(item){
      var planItemView = new app.PlanItemView({
          model: item,
          el: this.id
      });
      this.$("#the-plan").append(planItemView.render());
  }
});

...

var planView = new app.PlanView(test_plan_items);

What's wrong here?

Was it helpful?

Solution

Change the render function to :

render: function() {

    this.$el.append(this.template({
      "myPlan": this.collection
    }));

    this.collection.each(function(item){
      this.renderPlanItem(item);
    }, this);

    return this;
}

And change the renderDish to :

renderPlanItem: function(item){
    var planItemView = new app.PlanItemView({
        model: item,
        el: this.id
    });
    planItemView.render();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top