简体   繁体   中英

Backbone View + Events

Why is the event not triggered if I click the button or trigger the event? What do i miss?

<html>
<head><script src="jquery-1.7.1.js" type="text/javascript"></script>
<script src="underscore.js" type="text/javascript"></script>
<script src="backbone.js" type="text/javascript"></script>
<script type="text/javascript">

var SearchView = Backbone.View.extend({

    events: {
        "click #testid": 'savenow'
    },

    initialize: function(){
        console.log("init");
        console.log($('testid'));
    },

    savenow: function(){
        console.log("test save method");
    }
});

// The initialize function is always called when instantiating a Backbone View.
// Consider it the constructor of the class.
var search_view = new SearchView({ el: $('#testid') });
search_view.trigger("savenow", "test");
</script></head>
<body>
<h1>test</h1>
<input id="testid" type="button" value="testbutton" />
</body></html>

The example above is almost copied, but in my case it is not working.

Your having a few issues. As the others answers suggest, the events object needs to be changed. This will bind the click event to #testid by default since that is the el of the view. Some reading on the subject delegateEvents .

events: {
  'click' : 'savenow'
}

Your second problem is - the code is loading before the DOM is loaded. Which means, your view is unable to bind to the testid element. To fix this, you need to wrap your code in a document.ready() function.

<script type="text/template">
  $(function() {
      /* All your code
       ...
       ...
       */
  });

A third issue is when you call search_view.trigger("savenow", "test"); the savenow event is triggered, but nothing is listening for that event - so nothing appears to happen. You need to listen for that event on the view:

initialize: function(){
  console.log("init");
  this.on('savenow',this.savenow,this); 
   // or this.listenTo(this,'savenow',this.savenow);
}

A working code example:

<html>
  <head>
    <script src="jquery-1.7.1.js" type="text/javascript"></script>
    <script src="underscore.js" type="text/javascript"></script>
    <script src="backbone.js" type="text/javascript"></script>
    <script type="text/javascript">

      // Run this block of code when the DOM is loaded.
      $(function() {

        var SearchView = Backbone.View.extend({

          // Listen for click events on this view's element - '#testid'.
          events: {
            "click": 'savenow'
          },

          initialize: function(){
            console.log("init");
            // listen for the savenow event triggered by this view.
            this.listenTo(this,'savenow',this.savenow);
          },
          savenow: function(){
            console.log("test save method");
          }
        });

        var search_view = new SearchView({ el: '#testid' });
        search_view.trigger("savenow", "test");
      });
    </script>
  </head>
  <body>
    <h1>test</h1>
    <input id="testid" type="button" value="testbutton" />
  </body>
</html>

You're giving the el as #testid - Then, you're telling it to look inside #testid for #testid when you configure events: as

events:{
"click #testid":"savenow"
}

By changing the events object to

events:{
"click":"savenow"
}

You are just targeting all of the view's el (in this case, #testid).

Alternatively, you can keep your events configuration as you had it, and change the el to be body, or parent div of your search panel (which I assume contains the text input field or other settings, as well as the button).

events: {
    "click": 'savenow'
},

Here you go! Event type without a selector adds the event listener on the view el itself.

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