简体   繁体   中英

Backbone view: el and events

I am trying to play around with Backbone and have trouble with Views, in particular with "el" and events. I noticed I'm not the first one, but unfortunatelly could not find an optimal answer to my questions.

My base relevant code:

HTML:

<!DOCTYPE html>
<html>
    <head>
        <script data-main="main" src="js/require.js"></script>
    </head>
    <body>
        <div id="login"></div>
    </body>
</html>

VIEW:

var view = Backbone.View.extend({
        el: $("#login"),

        initialize: function() {
            this.el.html('<div>click here</div>');         // TypeError: this.el.html is not a function 
        }
.....

Question 1:

Please note the comment in the initialize() function, that's error registered by Firebug when I load this code.

But, when I only remove the "el" config and instead put the corresponding assignement in initialize() the run-time error is gone!

var view = Backbone.View.extend({
            //  "el" is now removed 

        initialize: function() {
            this.el = $("#login");                       // explicit assignement
            this.el.html('<div>click here</div>');       // appends the div correctly
        }
.....

Question 2: In both of these examples if I specify events in View's events config, the event never fires:

events: {
            "click":          "tryLogin"
          },
          ...

Please enlighten me! :)

The specific problem you're having is that this.el is not a jQuery object, and it has no .html method. That's what this.$el is for; this.el is a raw DOM element and this.$el is the jQuery-wrapped version of that object. You should not overwrite el with a jQuery-selected element.

The real problem you're having is that you're trying to modify the DOM in initialize .

If, in initialize , you want to access a DOM element that is already in the DOM, you need to pass an el: option to the view's constructor. Generally you shouldn't do this though. Your view should do its DOM manipulation in its render method.

From the docs :

If you'd like to create a view that references an element already in the DOM, pass in the element as an option: new View({el: existingElement})

In practice I've found that el and $el are still available, but you should avoid using them in initialize regardless. Stick to modifying the DOM in render , which is specifically where your view's "drawing" code is meant to go:

 var view = Backbone.View.extend({ el: '#login', render: function () { this.$el.append('<h1>What!</h1>'); return this; } }); $(function () { new view().render(); }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script> <div id="login"></div> 

In regards to Question 2, I cannot reproduce your problem. The following works exactly as expected:

 var View = Backbone.View.extend({ el: '#login', events: { 'click': 'onClick' }, onClick: function () { alert('click!'); }, render: function () { this.$el.append('<h1>What!</h1>'); } }); new View().render(); 
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script> <div id="login"></div> 

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