user18015
user18015

Reputation:

I'm doing something wrong with the events in this tiny Backbone app

I'm trying to understand how events work in Backbone. The following seems to me to be a pretty minimal example, so what am I doing wrong?

<!DOCTYPE html>
<html>
<head>
  <title>events</title>
  <meta charset="UTF-8">
  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.1.7/underscore-min.js"></script>
  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js"></script>
<script>
$(document).ready(function(){

  window.PasteView = Backbone.View.extend({
    el : '#paste',

    events : {
      'keyup' : 'callback',
    },

    initialize: function(){
      _.bindAll(this, 'render', 'callback');
    },

    render: function(){
    },
    callback : function(){
      $('body').append('<p>callback called</p>');
    }
  });

  window.paste = new PasteView;
})

</script>
</head>
<body>
<div id="paste">
  <p>Every time you hit a key there should be a console.log event</p>
  <textarea id="text" ></textarea>
</div>

</body>

</html>

Shouldn't the keyup event be firing the callback function?

Upvotes: 0

Views: 1190

Answers (3)

Derick Bailey
Derick Bailey

Reputation: 72868

there's several things that are missing and/or incorrect in this example.

Backbone's declarative events for views require a valid 'el' to be either specified directly (as your trying to do) or generated by the backbone view itself. all events are scoped within the context of the 'el', when the events are bound.

if you specify an el, as you've done here, then the element that you specify must exist within the html of the page at the time that the code is parsed. if you don't specify an el, then backbone will generate one for you.

here's a few examples:

sample #1

allow the el to be generated and click a button within it:

MyView = Backbone.View.extend({
  events: {
    "click #thatThing": "youClickedIt"
  },

  youClickedIt: function(){
    alert("you clicked it!");
  },

  render: function(){
    $(this.el).html("Click me");
    return this;
  }
});

$(function(){
  var el = new MyView().render().el;
  $("body").append(el);
});

and here's the HTML:

<html>
  <script src="...thisExample.js"></script>
  <script src="...jQuery.js"></script>
  <body>
  </body>
</html>

in this example, the "render" method will add a button to the el of the view (which is a div by default). the el (which now contains the button) is then appended to the body of the html. now when you click on the button, you'll see the alert box.

note that if the button does not exist within the el, clicking on it won't cause the alert box to show. the events you declare are always scoped to the el of the view.

sample #2

if you want to specify an 'el' to be an element in the page...

MyView = Backbone.View.extend({
  el: "#something",

  events: {
    "click #thatThing": "youClickedIt"
  },

  youClickedIt: function(){
    alert("you clicked it!");
  }
});

$(function(){
  var el = new MyView().render().el;
  $("body").append(el);
});

and here's the HTML:

<html>
  <script src="...thisExample.js"></script>
  <script src="...jQuery.js"></script>
  <body>
    <div id="something">
      <button id='thatThing'>Click me</button>
    </div>
  </body>
</html>

in this example, there is no "render" method because the html already exists. instead, we're just attaching the view to the existing "#something" div. the declared event, then, is scoped with the el and it will find the "thatThing" button. so when you click on it, you get the alert box.

note that if the button does not exist within the "something" el, clicking on it won't cause the alert box to show. the events you declare are always scoped to the el of the view.

hope that helps.

Upvotes: 2

Roland Hu&#223;
Roland Hu&#223;

Reputation: 2525

First of all, shouldn't PasteView extend Backbone.View and not Backbone.Model ?

Upvotes: 0

Overmind Jiang
Overmind Jiang

Reputation: 633

It seems that you do not have a body tag inside your html. Thus, $('body').append(...) will not work.

Upvotes: 0

Related Questions