Ankur
Ankur

Reputation: 791

Multiple Models using same View in Backbonejs

I'm a beginner in Backbone trying to get a sample page up and running with multiple instances of a Carousel. Here's how my HTML looks like

<div class="en-carousel" id="one" data-href="/js/models/json/carousel.json" data-content-id=""></div>
<div class="en-carousel" id="two" data-href="/js/models/json/carousel2.json" data-content-id=""></div>
<div class="en-carousel" id="three" data-href="/js/models/json/carousel3.json" data-content-id=""></div>

The data is fetched using the Model and the render method of view iterates over the 'el' object of my View object. The model fetch is associated with a success handler which initiates the carousel. The controller code looks like

define([
  'jquery',
  'backbone',
  'handlebars',
  'text!view/carousel.html',
  'plugin/jquery.bxslider.min',
  'TPL'
], function($, Backbone, Handlebars, carouselTemplate, $bx, TPL){

  var CarouselModel = Backbone.Model.extend({
    setURL: function(url){
      this.url = url;
    }
  });

  var CarouselView = Backbone.View.extend({
    el: '.en-carousel',
    model: new CarouselModel(),
    initialize: function () {

    },
    render: function () {
      var that = this;
      this.$el.each(function(){

        //that.model.url = $(this).data('href');
        that.model.setURL($(this).data('href'))

        that.listenTo(that.model,'change', that.onSuccess);
        that.model.fetch();

      });


    },

    onSuccess: function(response, status, xhr){

      var tpl = window["ENX"]["templates/handlebars/carousel.html"](this.model.get('response'));
      $(this.el).append(tpl);
      $(this.el).find('ul.carousel').bxSlider();

    },

    ajaxFail: function(){
      alert(2)
    }
  });
  return CarouselView;
});

I'm using Handlebars for templating. The problem here is the listenTo event is fired n*n times for n instances. So for 3 carousel I'm getting 9 carousels in total and all of them are being appended to div#one

Upvotes: 0

Views: 662

Answers (1)

jgillich
jgillich

Reputation: 76369

The solution is simple: replace the entire content of el when the model changes.

initialize: function () {
    this.model.fetch().done(function () {
        this.render();
        this.listenTo(this.model,'change', this.render.bind(this));
    }.bind(this));
},

render: function () {
    var tpl = window["ENX"]["templates/handlebars/carousel.html"](this.model.get('response'));
    this.$el.html(tpl);
    this.$el.find('ul.carousel').bxSlider();
}

There is also no need to iterate over el because it is just a single element.

Upvotes: 0

Related Questions