Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone rebinding events on a view

I have two views, one represents a view of clients and the other is the individual client views. I am binding the mouseenter and mouseleave events in the client view to fade in and out an overlay on the image. This works fine when it is by itself. However, I am also using a jQuery plugin to do a carousel effect (plugin here). Once that is enabled, my custom events no longer work. Is there any way I can delegate the Client View events after the plugin is initialized? This is my first time using Backbone so I might be doing something else wrong as well.

Here is the code:

// Client View
window.ClientView = Backbone.View.extend({
  tagName: 'li',
  template: _.template($("#client-template").html()),
  className: 'client-thumb',

  events: {
    "mouseenter": "fadeOutOverlay",
    "mouseleave": "fadeInOverlay"
  },

  initialize: function() {
  },

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

  fadeOutOverlay: function() {
    $(this.el).find(".slider-image-overlay").fadeOut('fast');
  },

  fadeInOverlay: function() {
    $(this.el).find(".slider-image-overlay").fadeIn('fast');
  }

});

// Clients View
window.ClientsView = Backbone.View.extend({
  el: "#clients",

  initialize: function() {
    this.collection.bind('all', this.render, this);
  },

  render: function() {
    var $clients = $("<ul class='clearfix'></ul>");
    _.each(this.collection.models, function(client) {
      var view = new ClientView({model: client});
      $clients.append(view.render().el);
    });

    $(this.el).hide().append($clients).fadeIn().scrollingCarousel();

    return this;
  }
});

EDIT: Here I am trying to delegateEvents() on the views that were created (the ones that have the events on them):

App.View.ClientsView = Backbone.View.extend({
  el: "#clients",

  initialize: function() {
    this.collection.bind('all', this.render, this);
  },

  render: function() {
    var $clients = $("<ul class='clearfix'></ul>");
    var views = [];
    _.each(this.collection.models, function(client) {
      var view = new App.View.ClientView({model: client});
      views.push(view); // Store created views in an array...
      $clients.append(view.render().el);
    });

    $(this.el).hide().append($clients).fadeIn().scrollingCarousel({
      // Use the plugin's callback to try to delegate events again
      afterCreateFunction: function() {
        _.each(views, function(view){
          view.delegateEvents();
        });
      }
    });

    return this;
  }
});

Tried this but doesn't seem to work? Am I doing it right? I think that the plugin is doing more than I think to the DOM. It looks like it is touching the elements I am trying to bind to as well as binding to mouseenter and mouseleave. I am unfamiliar with this plugin, doesn't look like it has an unminified version so I can't read it too well.

Any other suggestions?

like image 512
Brandon Avatar asked Feb 21 '12 15:02

Brandon


1 Answers

you can do that using delegateEvents method of your view to rebind your events

usage: myView.delegateEvents()

reference the documentation http://backbonejs.org/#View-delegateEvents for more info

edit:

this plugin binds and unbinds mouseenter/leave without namespacing - open the plugin script and add namespace to the event binding and unbinding.

apply these fixes to every occurence of these and it should be ok even without the delegateEvents()

r.unbind("mouseenter"); => r.unbind("mouseenter.carousel"); r.unbind("mouseleave"); => r.unbind("mouseleave.carousel");

r.mouseenter(function() { ... => r.bind('mouseenter.carousel', function() { ... r.mouseleave(function() { ... => r.bind('mouseleave.carousel', function() { ...

like image 141
Tom Tu Avatar answered Oct 16 '22 13:10

Tom Tu