简体   繁体   中英

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?

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() { ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM