7
votes

define events in Backbone.Model

var Todo = Backbone.Model.extend({
  initialize: function(){
    this.on('change', function(){
        console.log('- Values for this model have changed.');
    });
  }
})

define events in Backbone.View

var TodoView = Backbone.View.extend({
  className: "document-row",
  events: {
    "click .icon":          "open",
    "click .button.delete": "destroy"
  }
})

My Question

define events syntax are quite different between model/collection and view, why are they designed in that way?

I think it's better to define model event like this. But backbone don't support it.

var Todo = Backbone.Model.extend({
  events: {
    "change": "foo"
  },

  foo: function(){
    console.log("test")
  }
});
1
I do not know about the design choice. But if in case, you want to define events in model as done in views you can basically do something like this. It's just a rough example not a complete solution. - Sami
It's not that the syntax for defining events is different, but rather that there is no "special" (syntactic sugar) syntax for defining events on models. The syntax you are using on your model works just as well in a view or collection (since your really just binding the event directly). Further it doesn't really do the same thing since in a view your are delegating the events to the root el. - Jack

1 Answers

2
votes

There are two separate type of events: Backbone.Events and jQuery DOM events - so making these look the same seems like a bad idea as it would make code confusing not to mention it wouldn't actually work because the View UI events need different info: '<eventName> <optional DOM selector>: <methodName>' whereas normal internal events have a different syntax.

Backbone.Events follows the typical "publish/subscribe" pattern - it's just a way for apps to internally say "Something has happened" via .trigger and "I want to know when something happens" via .on or .once and the equivalent which you would use in a View because it handles cleaning up the listen when the view is removed: .listenTo and .listenToOnce.

So in your example the "change" event in the model is an internal event which Backbone fires when an attribute changes. The "change" in the View is jQuery DOM event (actually a delegate event) and you could optionally listen to something deeper in the view "change .myinput" so they are not equivalent.

The other difference is that .trigger can pass any arguments it likes after the first one (the event name), whereas the View event passes the DOM event object which you don't control e.g. onChange: function(ev) { ev.preventDefault(); }.