proper way to dynamically assign backbone.js view el

16,926

You don't actually need to go through all that "this.element" stuff.

Backbone automatically sets the view's "el" to the "el" you pass into the constructor as an option.

It is then available as "this.el" throughout the view.

This is all you need to do:

x = Backbone.View.extend({
    events: {
      'click': 'say_hi'
    },

    initialize: function( options ){
        // Not actually needed unless you're doing something else in here
    },

    say_hi: function(){
      alert( this.el.id );
    }

  });

y = new x( {el: '#div-1'} );
z = new x( {el: '#div-2'} );

z.say_hi();
y.say_hi();
​

See this live jsFiddle: http://jsfiddle.net/edwardmsmith/QDFwf/15/

The reason your second example did not work is that with the latest versions of Backbone, you cannot just set the "el" directly any more. This does not, as you noticed, properly set/update events.

Does not work

initialize: function( options ){
  this.el = options.el;
}

If you wanted to set the el dynamically that way, you need to use View.setElement as that properly delegates events and sets up the cached this.$el.

Works

initialize: function( options ){
  this.setElement(options.el)
}

Live jsFiddle of your second example: http://jsfiddle.net/edwardmsmith/5Ss5G/21/

But this is just re-doing what is already being done under the hood in Backbone.

Share:
16,926

Related videos on Youtube

kikuchiyo
Author by

kikuchiyo

Ruby on Rails / Javascript Developer and QA-Automation Engineer

Updated on September 15, 2022

Comments

  • kikuchiyo
    kikuchiyo about 1 year

    I would like to create two ( or more ) view instances, each with different el attributes, and have events bound to them via backbone.js view's events hash ( not through jQuery ).

    Getting events to trigger when all instantiations have the same el is easy:

    someView = Backbone.View.extend({
      el: '#someDiv',
    
      events: {
        'click': 'someFunction'
      },
    
      someFunction: function(){
        //Do something here
      }
    });
    

    So far, if I assign el in the initialize function, and set events normally as follows, events do not trigger:

    someView = Backbone.View.extend({
      events: {
        'click': 'someFunction'
      },
    
      initialize: function( options ){
        this.el = options.el
      },
    
      someFunction: function(){
        //Do something here
      }
    });
    

    My first instinct was to have el be a function that returns the string representation of the dom element of interest:

    someView = Backbone.View.extend({
      el: function(){
        return '#someDiv-' + this.someNumber
      },
    
      events: {
        'click': 'someFunction'
      },
    
      initialize: function( options ){
        this.someNumber = options.someNumber
      },
    
      someFunction: function(){
        //Do something here
      }
    });
    

    However, this triggers someFunction x times if I have x instantiations of someView.

    Next I tried setting both the el and events attributes in initialize:

    someView = Backbone.View.extend({
    
      initialize: function( options ){
        this.el = options.el
        this.events = {
          'click': 'someFunction'
        }
      },
    
      someFunction: function(){
        //Do something here
      }
    });
    

    but this does not trigger events. At this point I'm pretty much fishing.

    Does anyone know how instantiate a backbone.js view with an el specific to that instance that has events that only trigger for that instance, and not other instances of the View?

  • Edward M Smith
    Edward M Smith over 9 years
    Updated the two jsfiddles to source underscore and backbone from CDNjs instead of from github. Assuming that was the issue you were seeing.