2.6 Listening for Model Events
Backbone has a very robust events module that is available to all the components of the framework. In this lesson, we'll look at the events API, and then learn about the events that will occur on your models.
1.Getting Started3 lessons, 13:56
2.Backbone Models7 lessons, 38:03
3.Backbone Collections6 lessons, 17:52
4.Backbone Views4 lessons, 26:08
5.Backbone Routers3 lessons, 11:19
6.Conclusion1 lesson, 01:36
2.6 Listening for Model Events
In this lesson, we're going to talk about events with Backbone models. Backbone has a pretty great event system. It fires events for quite a few different actions throughout the life cycle of your application. And you can listen for those events and perform other actions when they occur, or even trigger your own events. And these methods that we're going to look at right now work for all of the different objects, whether it's a Backbone model, a collection, or a view. So you're probably pretty familiar with these first three methods, which is obj.on, obj.once, and obj.off. And these are pretty familiar syntaxes if you've worked with something like jQuery. You can wait for an event, which is the first parameter to the on, once, or off method to occur on a given object. And when that happens, you can have a certain function be called. And if you want, you can set a context, or whatever object will be the value of this, within this function when it's called. On, of course, listens for every occurrence of that event on this object and will call the function each time. If you use object.once, this will only listen for the first time this event occurs and then stop listening after that. And finally, you can turn off event listeners by using object.off and passing the same function signature as you did for on, for example, to turn off listening on that event. Now this is kind of the older syntax. What is perhaps better to use these days is the listenTo syntax. And the reason this syntax is a little better, is because it allows the part of the code that performs the function to keep track of those events instead of the objects on which the events are occurring. So notice with this first syntax on line eight here. If we wanted to keep track of all of the, say, change events that occur on a specific model, using this syntax, we would have to keep track of that list of event listeners within this object here. And so the only place where we could then turn off these event listeners is from that same object. However, this object is not the one performing the function call, it's these other functions that are being called, right, and these functions may be within a view, right? So, we might say we have some model here, say a book, and we want to listen for a change title event. And when that change title event occurs, the function is going to be view.changeTitle, for example, right? But what if that view is not currently being displayed on the page? Right, if the view has come and gone and has since been destroyed, there's no reason to call that function anymore. However, the model on which the events are occurring, in this case, the book, doesn't know that the view no longer exists. And so it could still go and look and try to call that. And there probably won't be any errors if it can't find that. However, the problem is that event listener is still taking up room in memory. It doesn't really allow you to clean up after a view when a view has been destroyed. If we do it this way instead, on line 14 here, we are creating this event connection from the view. So we say view.listenTo an object, in this case our book, and we're listening for a change title event, and we want to call the specific function. Probably something on the view itself, but it doesn't have to be. In any case, the view itself is listening to this object, right. And most likely it's listening for like a change event or something that it will want to do to update itself. The view when that model changes. And so, when the view is destroyed, it can get rid of its list of event handlers and therefore we won't have event handlers piling up as the user created and destroyed. So that's why it's better to use this syntax here. As you can see, we have listenTo and listenToOnce, which are kind of the versions of on and once. We have pretty much the same set of objects here. Here we have object, event, function, and context. Here we have object, event, function, and the context actually for these is going to be the view itself, so you don't have to set that context. And finally here, you can see we have the view.stopListening method. This function is something that you probably won't call very often by yourself, but it will be called behind the scenes when a view is destroyed. So this is the event syntax for all of the different Backbone objects. You can use these all these events from anyone of these Backbone objects. So as I just said, this stuff is true for all of the different Backbone components. However, this here is the list of events that can occur on a model. So whenever you change an attribute using the set or unset something like that, the change event will be fired. If you wanna listen for a change in a specific attribute, you can do change colon field name. So I could say for example, change:author, if I wanna listen specifically for changes of the author field. When a model is destroyed, the destroy event will occur. Whenever a request is made to the server for anything. Whether that's creating, updating, deleting, or reading, the request event will occur. When the request returns successfully, the sync event happens, and if the request fails for some reason, an error event will happen. When validation is run, we talked about that in a previous lesson, if the model is not valid, the invalid event will occur. And finally we have the all event which happens in every single case. So no matter what event happens, all will always be fired as well. So, it's possible that multiple events will be fired at a time. So for example, if we use, say book.save and we set the author to something while we're doing book.save. Well then, the change event will probably occur, change:author will definitely occur. A request will occur. Sync will probably occur if it happens successfully, or error if it doesn't. And, all of course, will occur as well. And so, you could make one line of code here fire one, two, three, four different event listeners. All right, so let's actually give this a try, shall we? Let's create a book here and let's do the id, setting it to one so that we can pull that from the server and we'll do book.fetch. Where we'll usually create these handlers, they'll probably be within views or something like that. For example, you might create a view to display an individual model and you'll have that view specifically looking for changes, right? So, but for now, let's do book.fetch to fetch it from the server. And let's see what's our index.html page looking like. We have a main div here. Okay, so let's get that div. I'll say var main equals. Actually we have jQuery, so I may as well use that. Then, fetch here actually returns a promise. So I can now use it like this and we can say. Actually, let's create a function down here that is like a view function. We'll say updateView, and in here, we'll just set main.text equal to book.get title. There we go, and so in here we can call updateView. And then, let's also say book.on, change:title, and then we will say updateView, there we go. So now, when we initially create the page, we will update the view. And actually, we probably don't even have to call this because the change event may occur when the fetch event happens. Actually, I think that's the case. So, let's go ahead and let's give that a try. 90% sure that will happen. Okay, so if we come to our server here. And let's refresh the page. And it looks like we have a little problem. Oh, the problem is of course we're expecting _id. Right, of course. So, let's just set that. And now, if we refresh the page. And there you go, notice we get Sign of the Four displaying there. So yeah, that worked fine. When we did this fetch, it did cause the change title event to occur, which in turn updated our view for us. We could actually go ahead and update this manually if we do book.set, and we will set the title to something else. And you can see that the view updates accordingly something else. So that is a quick look at how you can use Backbone models. Of course, in this context it seems rather small. But I promise you this event functionality is definitely a lot more useful when you have many views and many models and you're creating a complex front end application.