0

I have the following structure:

var PopupView = Backbone.View.extend({
  el:'#shade',
  events:{
    'click .popup-cancel': 'hide',
    'click .popup-commit': 'commit',
  },
  show: function(){
    ...
  },
  hide: function(){
    ...
  },
  initialize: function(){
    _.bindAll(this, 'show','hide','commit');
  }
});

var Popup1 = PopupView.extend({
  render: function(){
    ...
  },
  commit: function(){
    console.log('1');
    ...
  },
});

var Popup2 = PopupView.extend({
  render: function(){
    ...
  },
  commit: function(){
    console.log('2');
    ...
  },
});

The problem is that when I click .popup-commit from one of the popups, it actually triggers the methods of both of them. I've tried moving the declaration of events and initialize() up into the child classes, but that doesn't work.

What's going on, and how can I fix it (so that the commit method of only the view I'm triggering it on gets fired)?

mu is too short
  • 426,620
  • 70
  • 833
  • 800
fredley
  • 32,953
  • 42
  • 145
  • 236

1 Answers1

2

Your problem is right here:

el:'#shade'

in your PopupView definition. That means that every single instance of PopupView or its subclasses (except of course those that provide their own el) will be bound to the same DOM node and they will all be listening to events on on id="shade" element.

You need to give each view its own el. I'd recommend against ever setting el in a view definition like that. I think you'll have a better time if you let each view create (and destroy) its own el. If you do something like:

var PopupView = Backbone.View.extend({
  className: 'whatever-css-class-you-need',
  tagName: 'div', // or whatever you're using to hold your popups.
  attributes: { /* whatever extra attributes you need on your el */ },
  //...
});

then your views will each get their own el. See the Backbone.View documentation for more information on these properties.

mu is too short
  • 426,620
  • 70
  • 833
  • 800