1 00:00:00,000 --> 00:00:02,000 [?music?] 2 00:00:02,000 --> 00:00:06,000 [Creating List Views] 3 00:00:06,000 --> 00:00:09,000 [Jim Hoskins] So now we've defined our collection, which you can think of 4 00:00:09,000 --> 00:00:14,000 as a model that's really modeling a list of models, or an aggregation of models, 5 00:00:14,000 --> 00:00:17,000 and this is going to be great because we're going to be creating a list 6 00:00:17,000 --> 00:00:20,000 of all of the items, so when we create a ListView, 7 00:00:20,000 --> 00:00:25,000 that View can observe the collection and get its data 8 00:00:25,000 --> 00:00:27,000 from our NoteList collection. 9 00:00:27,000 --> 00:00:30,000 So let's actually create the View for our list. 10 00:00:30,000 --> 00:00:33,000 I'm going to come down here to where we're defining our views 11 00:00:33,000 --> 00:00:39,000 and we'll just define a new View. 12 00:00:39,000 --> 00:00:43,000 So I'm going to start out by creating a view called the NoteListView, 13 00:00:43,000 --> 00:00:48,000 and this will represent a full list of all of the notes in our application. 14 00:00:48,000 --> 00:00:52,000 So we'll call it var NoteListView 15 00:00:52,000 --> 00:00:59,000 and to create a View, we'll just extend the Backbone.View class 16 00:00:59,000 --> 00:01:01,000 just by calling .extend({ 17 00:01:01,000 --> 00:01:06,000 and we'll pass it an object with all of the methods that we want to add. 18 00:01:06,000 --> 00:01:10,000 So the first thing I want to do is create an initializer for my Views, 19 00:01:10,000 --> 00:01:13,000 so when I initialize a NoteListView, 20 00:01:13,000 --> 00:01:15,000 there's a few things that I want to do, 21 00:01:15,000 --> 00:01:24,000 so we do that by creating a function called initialize: function(){. 22 00:01:24,000 --> 00:01:27,000 Now, our View is going to have a property called the collection, 23 00:01:27,000 --> 00:01:32,000 and the collection is going to be an instance of a NoteList collection 24 00:01:32,000 --> 00:01:34,000 that represents all of our notes on the list. 25 00:01:34,000 --> 00:01:39,000 Now, we're going to actually pass this collection in when we instantiate 26 00:01:39,000 --> 00:01:43,000 the particular View here because we may want different ListViews 27 00:01:43,000 --> 00:01:45,000 watching different collections, 28 00:01:45,000 --> 00:01:52,000 but once it's initialized, we will be able to access it from this.collection, 29 00:01:52,000 --> 00:01:55,000 and this.collection is a NoteList. 30 00:01:55,000 --> 00:02:03,000 The first thing we want to do is bind or listen for the ("add") event. 31 00:02:03,000 --> 00:02:09,000 The ("add") event on a collection is called when a new item is added to the list. 32 00:02:09,000 --> 00:02:12,000 Now, in our particular case, this actually doesn't come up very much, 33 00:02:12,000 --> 00:02:16,000 but this turns out to be a pretty common pattern in Backbone applications. 34 00:02:16,000 --> 00:02:21,000 You want to handle the case of adding a single item to a collection 35 00:02:21,000 --> 00:02:24,000 and then we're also going to handle the refresh event 36 00:02:24,000 --> 00:02:28,000 which happens any time there are large changes to the collection itself; 37 00:02:28,000 --> 00:02:31,000 for instance, when it's initialized and all the items are added in, 38 00:02:31,000 --> 00:02:34,000 or a fetch is called and multiple items are added in-- 39 00:02:34,000 --> 00:02:37,000 that will trigger the refresh action. 40 00:02:37,000 --> 00:02:42,000 So when we're jjust adding one, we're going to tie this to a method in our View 41 00:02:42,000 --> 00:02:46,000 we'll call this.addOne);. 42 00:02:46,000 --> 00:02:54,000 So this will be when we addOne, we will write the code for adding a single item into our list. 43 00:02:54,000 --> 00:02:57,000 Similarly, we're going to look at this.collection 44 00:02:57,000 --> 00:03:01,000 and .bind to the ("refresh") action, 45 00:03:01,000 --> 00:03:05,000 which is when a large change takes place to the collection, 46 00:03:05,000 --> 00:03:11,000 and we will create a method called this.addAll);. 47 00:03:11,000 --> 00:03:15,000 Now what I'm going to do is just add in some blank functions 48 00:03:15,000 --> 00:03:18,000 to handle addOne and addAll. 49 00:03:18,000 --> 00:03:27,000 So I'll create addOne: function(){ and I'll do addAll: function(){. 50 00:03:27,000 --> 00:03:32,000 Now, in these event bindings, we're just passing the method into this function here, 51 00:03:32,000 --> 00:03:39,000 and this has an interesting side effect and now the function is sort of decoupled from this View. 52 00:03:39,000 --> 00:03:41,000 So in a normal circumstance, 53 00:03:41,000 --> 00:03:45,000 if this.addOne was called as a result of this binding, 54 00:03:45,000 --> 00:03:50,000 the this inside of addOne would not be associated with the View 55 00:03:50,000 --> 00:03:53,000 but perhaps the window or something else. 56 00:03:53,000 --> 00:03:56,000 So there are different ways we could handle this, 57 00:03:56,000 --> 00:03:58,000 but included in the Underscore library 58 00:03:58,000 --> 00:04:03,000 is an awesome function called bindAll, and we're going to call that up here. 59 00:04:03,000 --> 00:04:07,000 So to call it, we use the _ variable, which is globally available, 60 00:04:07,000 --> 00:04:10,000 and we call _.bindAll(). 61 00:04:10,000 --> 00:04:16,000 And what bindAll does is it takes a list of functions and it modifies them, 62 00:04:16,000 --> 00:04:21,000 so no matter how they're called, the this will always be a certain value. 63 00:04:21,000 --> 00:04:27,000 So the first argument is going to be what this should be any time these methods are called. 64 00:04:27,000 --> 00:04:32,000 and of course, we want the this to be, well, (this), 65 00:04:32,000 --> 00:04:35,000 which in this current context is this View. 66 00:04:35,000 --> 00:04:43,000 And the methods that we want to bind are "addOne", "addAll") 67 00:04:43,000 --> 00:04:47,000 So no matter how we call these methods, addOne and addAll, 68 00:04:47,000 --> 00:04:52,000 the this will be correct and predictable no matter what 69 00:04:52,000 --> 00:04:57,000 and bindAll is what allows us to pass in simply the method reference 70 00:04:57,000 --> 00:05:02,000 instead of an anonymous function that calls this.addOne 71 00:05:02,000 --> 00:05:04,000 or any other tricky stuff. 72 00:05:04,000 --> 00:05:10,000 So now we're totally safe to use this in the context of addOne and addAll. 73 00:05:10,000 --> 00:05:14,000 It's just a handy little trick that allows us to write less code 74 00:05:14,000 --> 00:05:19,000 and remove some confusing parts of how this is applied in JavaScript. 75 00:05:19,000 --> 00:05:24,000 The last thing I want to do in the initialize here is make sure that my collection is up to date, 76 00:05:24,000 --> 00:05:29,000 so what I'm going to do here is I'm just going to call this.collection.fetch();. 77 00:05:29,000 --> 00:05:32,000 What this will do is make the collection look into the store, 78 00:05:32,000 --> 00:05:37,000 grab any new items, and then it will eventually call a refresh 79 00:05:37,000 --> 00:05:40,000 which will call our addOne and addAll functions 80 00:05:40,000 --> 00:05:45,000 which will update our user interface. 81 00:05:45,000 --> 00:05:50,000 The NoteList View represents a list of all of the notes in our application, 82 00:05:50,000 --> 00:05:55,000 but each item of that list itself has to manage its own changes. 83 00:05:55,000 --> 00:05:59,000 For instance, each item represents a specific note, and if that note changes its title 84 00:05:59,000 --> 00:06:03,000 or any other information, we want that to be reflected in each of the list items. 85 00:06:03,000 --> 00:06:07,000 So what we're actually going to do is create another View 86 00:06:07,000 --> 00:06:13,000 called a NoteListItem View, and each NoteListItem View will be associated 87 00:06:13,000 --> 00:06:15,000 directly to a specific instance of a note. 88 00:06:15,000 --> 00:06:19,000 So our NoteListView is watching the collection of notes, 89 00:06:19,000 --> 00:06:24,000 but the NoteListItemView is only concerned with a specific note. 90 00:06:24,000 --> 00:06:32,000 So let's look at how we would add a new ListItem into our NoteListView. 91 00:06:32,000 --> 00:06:37,000 In addOne, what we're going to do is construct a new NoteListItemView. 92 00:06:37,000 --> 00:06:40,000 Now, we haven't defined that yet, but we're going to write it out as though we had 93 00:06:40,000 --> 00:06:44,000 and then we'll write the code to make it work. 94 00:06:44,000 --> 00:06:47,000 A lot of times when we're coding, we get into the situation where 95 00:06:47,000 --> 00:06:50,000 we have two intertwined ideas, but we don't need to know too much 96 00:06:50,000 --> 00:06:53,000 about how the NoteListItemView is going to work, 97 00:06:53,000 --> 00:06:57,000 so let's just write it out, and then we can get our next View set up. 98 00:06:57,000 --> 00:07:00,000 So when adding One, the first thing we want to do 99 00:07:00,000 --> 00:07:03,000 is initialize the View for this particular list item, 100 00:07:03,000 --> 00:07:06,000 so we're going to call var view = 101 00:07:06,000 --> 00:07:12,000 and we'll just call new NoteListItemView({}); 102 00:07:12,000 --> 00:07:15,000 and to this, we're going to pass the actual instance of the note 103 00:07:15,000 --> 00:07:18,000 that will be used for that particular list item. 104 00:07:18,000 --> 00:07:22,000 Now, addOne takes one argument and that will be the instance of our note model, 105 00:07:22,000 --> 00:07:24,000 so we'll call that (note){. 106 00:07:24,000 --> 00:07:30,000 So we're going to associate this instance of a ListItemView with this particular note 107 00:07:30,000 --> 00:07:32,000 that is passed into addOne. 108 00:07:32,000 --> 00:07:37,000 So we'll say ({model: note}) 109 00:07:37,000 --> 00:07:40,000 and this model attribute for the node ListItemView 110 00:07:40,000 --> 00:07:43,000 is a lot like the collection of this NoteListView. 111 00:07:43,000 --> 00:07:49,000 It's really what this View is listening to and is focused on. 112 00:07:49,000 --> 00:07:52,000 So now we have the View for this particular model, 113 00:07:52,000 --> 00:08:00,000 and what we want to do is we want to add that View into our View as a child. 114 00:08:00,000 --> 00:08:05,000 Now, all Views have an .el element, which we saw in our form View, 115 00:08:05,000 --> 00:08:09,000 which represents the actual node in the document that is rendering our View. 116 00:08:09,000 --> 00:08:13,000 And so what we want to do is we want to append into it 117 00:08:13,000 --> 00:08:18,000 the contents of our subview or our ListItemView. 118 00:08:18,000 --> 00:08:21,000 So what we'll do is we use jQuery 119 00:08:21,000 --> 00:08:23,000 and we'll wrap that around $(this.el) 120 00:08:23,000 --> 00:08:28,000 so now we have a jQuery instance representing the element 121 00:08:28,000 --> 00:08:30,000 of the ListItemView. 122 00:08:30,000 --> 00:08:34,000 And then, we're going to call the jQuery method append() 123 00:08:34,000 --> 00:08:39,000 and then we want to pass it in the code that we want to append to our ListView 124 00:08:39,000 --> 00:08:45,000 and that's going to be the element that our NoteListItemView will render. 125 00:08:45,000 --> 00:08:47,000 Now I'm going to type in this code. 126 00:08:47,000 --> 00:08:51,000 (view.render().el) 127 00:08:51,000 --> 00:08:55,000 So what's going on here is we're taking our view and we're calling a render method 128 00:08:55,000 --> 00:08:59,000 which we're going to write itself, and this render method is going to take the information 129 00:08:59,000 --> 00:09:02,000 from the model associated with that ListItemView 130 00:09:02,000 --> 00:09:06,000 and turn it into some HTML and save it to its own element. 131 00:09:06,000 --> 00:09:10,000 Then, it's going to return itself, and we can get the .el property 132 00:09:10,000 --> 00:09:14,000 or the element of that ListItemView 133 00:09:14,000 --> 00:09:17,000 and then we'll simply append it to this element, 134 00:09:17,000 --> 00:09:21,000 so we're rendering a view within a view here. 135 00:09:21,000 --> 00:09:23,000 Now, that should work well enough. 136 00:09:23,000 --> 00:09:26,000 The next step is we want to implement this.addAll 137 00:09:26,000 --> 00:09:29,000 and this will be happening any time that the collection is refreshed 138 00:09:29,000 --> 00:09:32,000 or a major change has been made to the set. 139 00:09:32,000 --> 00:09:38,000 This is going to be pretty easy; we'll use jQuery to wrap around $(this.el) 140 00:09:38,000 --> 00:09:42,000 and we'll empty() it out because we're going to have potentially several ListItems 141 00:09:42,000 --> 00:09:46,000 already in our View and we want to clear it out before we start adding more. 142 00:09:46,000 --> 00:09:52,000 Otherwise, we're bound to get duplicates if this addAll function is called over and over again. 143 00:09:52,000 --> 00:10:00,000 So we empty out this View and then we can call this.collection.each, 144 00:10:00,000 --> 00:10:03,000 and .each is a method on the collection class 145 00:10:03,000 --> 00:10:07,000 which will take in a function and apply that function 146 00:10:07,000 --> 00:10:11,000 and pass in one of the models each time it applies it, 147 00:10:11,000 --> 00:10:17,000 so for each item in the collection, we want to call (this.addOne);. 148 00:10:17,000 --> 00:10:20,000 So when we refresh, if there are ten items in the collection, 149 00:10:20,000 --> 00:10:31,000 collection.each will call this.addOne ten times, each time with a different note. 150 00:10:31,000 --> 00:10:36,000 So now we've defined the view that represents the full list of our elements, 151 00:10:36,000 --> 00:10:39,000 but now we need to define the view that represents the specific item in that list 152 00:10:39,000 --> 00:10:49,000 and we already decided we're going to call it var NoteListItemView = 153 00:10:49,000 --> 00:10:53,000 and we're simply going to extend Backbone.View again. 154 00:10:53,000 --> 00:10:56,000 Backbone.View.extend({ 155 00:10:56,000 --> 00:11:00,000 This view is going to be a little bit different from the form View we designed 156 00:11:00,000 --> 00:11:03,000 as well as the ListView we just defined 157 00:11:03,000 --> 00:11:07,000 in that the NoteListItemView is going to be generated programatically. 158 00:11:07,000 --> 00:11:11,000 We're not going to be attaching it to an existing element on the page. 159 00:11:11,000 --> 00:11:15,000 Instead, this View is going to be responsible for creating its own element, 160 00:11:15,000 --> 00:11:18,000 which will be an li for use in an unordered list. 161 00:11:18,000 --> 00:11:21,000 So the way we define things is going to be a little bit different. 162 00:11:21,000 --> 00:11:27,000 Instead of passing it an el element, instead, we're going to define what kind of tagName 163 00:11:27,000 --> 00:11:30,000 or what kind of class name we want to have 164 00:11:30,000 --> 00:11:33,000 for the element that it's going to generate automatically. 165 00:11:33,000 --> 00:11:36,000 So I'm going to define that for a NoteListItemView, 166 00:11:36,000 --> 00:11:40,000 I want the tagName to be "LI". 167 00:11:40,000 --> 00:11:43,000 So this means when we instantiate a NoteListItemView, 168 00:11:43,000 --> 00:11:46,000 since we're not going to pass in an el element, 169 00:11:46,000 --> 00:11:49,000 instead, Backbone is going to create an li element 170 00:11:49,000 --> 00:11:53,000 and set that to our el element internally. 171 00:11:53,000 --> 00:11:56,000 Now, let's go ahead and create our initializer, 172 00:11:56,000 --> 00:12:00,000 so we'll create initialize: function(){ 173 00:12:00,000 --> 00:12:05,000 and remember that the NoteListItemView has a model associated with it. 174 00:12:05,000 --> 00:12:08,000 Remember when we passed in the model 175 00:12:08,000 --> 00:12:10,000 when we instantiate each of our NoteListItemViews 176 00:12:10,000 --> 00:12:15,000 that's going to be available to us in the this.model variable. 177 00:12:15,000 --> 00:12:19,000 And so what we want to do with this model is bind or listen 178 00:12:19,000 --> 00:12:22,000 for the event called ("change"), 179 00:12:22,000 --> 00:12:27,000 and the change event will be called any time that a property is changed in our model. 180 00:12:27,000 --> 00:12:31,000 So for instance, if we changed the title, the model's going to broadcast that it changed 181 00:12:31,000 --> 00:12:34,000 and we want to know about that because we want to change 182 00:12:34,000 --> 00:12:36,000 how our View is displayed to the user. 183 00:12:36,000 --> 00:12:42,000 So any time we call change, we're going to call this.render. 184 00:12:42,000 --> 00:12:45,000 Now, again, since I'm just passing in a reference to a method, 185 00:12:45,000 --> 00:12:49,000 we need to use bindAll on the render method that we're about to write 186 00:12:49,000 --> 00:12:54,000 in order to make sure that this is always correct inside of the render method. 187 00:12:54,000 --> 00:13:00,000 So at the top here, I'm just going to call _.bindAll(this, 188 00:13:00,000 --> 00:13:04,000 and I'm going to bindAll for "render"). 189 00:13:04,000 --> 00:13:10,000 Our next step is to render our actual item 190 00:13:10,000 --> 00:13:13,000 so we're going to create a render method: 191 00:13:13,000 --> 00:13:16,000 render: function(){. 192 00:13:16,000 --> 00:13:20,000 We could do this any which way; we could hard encode a string as a template 193 00:13:20,000 --> 00:13:26,000 for creating our li item because basically what we need to do is to create an li 194 00:13:26,000 --> 00:13:33,000 with an <a> tag and a link to the correct URL in order to dig into it. 195 00:13:33,000 --> 00:13:37,000 While we could construct this using simple strings inside of our application, 196 00:13:37,000 --> 00:13:40,000 we kind of want to keep this separate because that's more presentational 197 00:13:40,000 --> 00:13:45,000 and View information and less behavioral, so we don't really want to start defining HTML 198 00:13:45,000 --> 00:13:47,000 inside of our JavaScript. 199 00:13:47,000 --> 00:13:51,000 Fortunately, the Underscore library that Backbone includes 200 00:13:51,000 --> 00:13:54,000 has a templating function. 201 00:13:54,000 --> 00:13:58,000 You can learn a little bit more about templating in the Underscore documentation 202 00:13:58,000 --> 00:14:00,000 on the underscore.template method. 203 00:14:00,000 --> 00:14:02,000 documentcloud.github.com/underscore/#template 204 00:14:02,000 --> 00:14:05,000 Backbone itself integrates the template method into its own classes, 205 00:14:05,000 --> 00:14:09,000 but it uses the same syntax and the same underlying code. 206 00:14:09,000 --> 00:14:12,000 Basically, we can create a rendered template 207 00:14:12,000 --> 00:14:14,000 by passing in a string. 208 00:14:14,000 --> 00:14:20,000 We can use a special <%= syntax to inline various pieces of code 209 00:14:20,000 --> 00:14:24,000 and data that can be re-rendered each time. 210 00:14:24,000 --> 00:14:30,000 This is much like an ERB template or using echo tags in PHP. 211 00:14:30,000 --> 00:14:33,000 Basically we have pieces of static code and pieces of dynamic code 212 00:14:33,000 --> 00:14:38,000 that are contained within special delimiters like this. 213 00:14:38,000 --> 00:14:41,000 So I could create that template string right here, 214 00:14:41,000 --> 00:14:44,000 but what I'm going to do is we're going to go into the index.html file 215 00:14:44,000 --> 00:14:51,000 and we're actually going to create our template string there. 216 00:14:51,000 --> 00:14:54,000 Now, we're going to do this using a trick with script tags 217 00:14:54,000 --> 00:15:01,000 and what we're going to do is create a <script> </script> 218 00:15:01,000 --> 00:15:09,000 and we're going to give it a type="text/template">. 219 00:15:09,000 --> 00:15:12,000 Now, that type doesn't really mean anything specific to a browser, 220 00:15:12,000 --> 00:15:17,000 but what it does do is it says it's not JavaScript so don't try to parse it like JavaScript. 221 00:15:17,000 --> 00:15:22,000 Basically, it allows us to create a script where we can store a string within our HTML. 222 00:15:22,000 --> 00:15:29,000 Now, in order to retrieve it, I'm going to give it an id="note-list-item-template">. 223 00:15:29,000 --> 00:15:34,000 So whatever you put in here won't show up in the flow of the page 224 00:15:34,000 --> 00:15:36,000 and it won't be executed. 225 00:15:36,000 --> 00:15:39,000 Basically, it's just sort of storing a string inside of our HTML, 226 00:15:39,000 --> 00:15:44,000 and since this will be defining HTML which will be rendered as a template, 227 00:15:44,000 --> 00:15:46,000 it makes sense to keep it in our HTML file 228 00:15:46,000 --> 00:15:50,000 so all of our HTML code is in one place. 229 00:15:50,000 --> 00:15:54,000 So basically, what we want to do in our template 230 00:15:54,000 --> 00:15:59,000 is create a template for what's inside of the list item of our NoteListItemView, 231 00:15:59,000 --> 00:16:03,000 so all of this code is going to be injected within an li for our View. 232 00:16:03,000 --> 00:16:06,000 Basically, all we need to do is create the <a> tag, 233 00:16:06,000 --> 00:16:10,000 so I'm going to create an <a tag with an href 234 00:16:10,000 --> 00:16:13,000 and we'll fill that in in a second. 235 00:16:13,000 --> 00:16:16,000 And then, we need to have some sort of text here: 236 00:16:16,000 --> 00:16:18,000 >TEXT</a>. 237 00:16:18,000 --> 00:16:22,000 And in a couple of places, we need to put dynamic information. 238 00:16:22,000 --> 00:16:27,000 Now, where I want the href to go is going to actually be a detailed view of our Note 239 00:16:27,000 --> 00:16:33,000 and we want to make sure that each of these has a URL that's unique to that Note 240 00:16:33,000 --> 00:16:37,000 because we always want to be able to get back to that Note using the URL. 241 00:16:37,000 --> 00:16:41,000 So something I'd like to do is have it be like "#note 242 00:16:41,000 --> 00:16:47,000 and then the ID, so if it was Note ABC, it would be "#note_abc". 243 00:16:47,000 --> 00:16:50,000 So the "#note_ is going to be static 244 00:16:50,000 --> 00:17:00,000 and then we're going to use these dynamic tags, the <%= and the %> to close. 245 00:17:00,000 --> 00:17:04,000 Anything in between these tags is going to be JavaScript 246 00:17:04,000 --> 00:17:07,000 and the result of the JavaScript expression inside of that 247 00:17:07,000 --> 00:17:11,000 is going to replace this whole piece of text right here, 248 00:17:11,000 --> 00:17:16,000 so if this returns the string ABC, all of this when the template is rendered 249 00:17:16,000 --> 00:17:20,000 will result down to note_abc. 250 00:17:20,000 --> 00:17:23,000 Now, our template is going to be passed a variable called Note, 251 00:17:23,000 --> 00:17:27,000 and we'll see that when we actually call render on this. 252 00:17:27,000 --> 00:17:32,000 We're going to have note as the model or the instance of our note, 253 00:17:32,000 --> 00:17:36,000 and there's a property on the note called id, which is the unique identifier 254 00:17:36,000 --> 00:17:41,000 used by Backbone in the system, and that's a great identifier for us to use. 255 00:17:41,000 --> 00:17:47,000 So then, inside of the <a> tag, what we want to do is we also want to put the title of our note, 256 00:17:47,000 --> 00:17:50,000 so here we're going to again create these dynamic output tags 257 00:17:50,000 --> 00:17:53,000 with <%= to open 258 00:17:53,000 --> 00:17:56,000 and then %> to close. 259 00:17:56,000 --> 00:18:00,000 Now, in order to get the title attribute, we need to use the get method 260 00:18:00,000 --> 00:18:04,000 and pass it in title like we saw earlier when working with models. 261 00:18:04,000 --> 00:18:08,000 We're going to take the note.get() 262 00:18:08,000 --> 00:18:15,000 and get the ("title") and now the title should be part of our template. 263 00:18:15,000 --> 00:18:18,000 So now that we have this template, I'm going to copy this id 264 00:18:18,000 --> 00:18:21,000 because we need to get it back. 265 00:18:21,000 --> 00:18:26,000 In this View for organization, I'm going to create a property called the template 266 00:18:26,000 --> 00:18:31,000 and this will be the template we use any time we render the View. 267 00:18:31,000 --> 00:18:37,000 In order to create a template, I call _.template($ 268 00:18:37,000 --> 00:18:43,000 and we'll call the jQuery function for ("note-list-item-template") 269 00:18:43,000 --> 00:18:47,000 so now we have the jQuery reference, and to get the contents of it, 270 00:18:47,000 --> 00:18:51,000 we're just going to .html()) so in effect, we're passing in the string 271 00:18:51,000 --> 00:18:56,000 that's inside of our note-list-item-template script tag into the template, 272 00:18:56,000 --> 00:19:02,000 and now we have a templating function stored in this .template. 273 00:19:02,000 --> 00:19:07,000 So our render is we're going to get the jQuery reference to $(this.el) 274 00:19:07,000 --> 00:19:13,000 and we're going to call the HTML function and pass it the HTML we want placed in it. 275 00:19:13,000 --> 00:19:16,000 In order to actually render our template with specific information, 276 00:19:16,000 --> 00:19:21,000 we'll call (this.template({ 277 00:19:21,000 --> 00:19:25,000 and we're going to pass it an object where the keys are going to be the variables 278 00:19:25,000 --> 00:19:28,000 available when rendering the template 279 00:19:28,000 --> 00:19:32,000 and the values will be the values for those variables. 280 00:19:32,000 --> 00:19:35,000 Now, remember, we used the note variable inside of our template, 281 00:19:35,000 --> 00:19:39,000 so we'll define note: this.model 282 00:19:39,000 --> 00:19:43,000 so this note right here 283 00:19:43,000 --> 00:19:48,000 makes it available in our actual template definition here. 284 00:19:48,000 --> 00:19:52,000 So this note is the same as this note. 285 00:19:52,000 --> 00:19:58,000 And so now we've updated our .el element with the template contents 286 00:19:58,000 --> 00:20:04,000 and what we want to do is return this; 287 00:20:04,000 --> 00:20:08,000 and that's because when we actually call render in the NoteListView, 288 00:20:08,000 --> 00:20:10,000 we call view.render 289 00:20:10,000 --> 00:20:14,000 so that means the view has now updated it to .el element. 290 00:20:14,000 --> 00:20:19,000 The render returns itself so we can then access the .el element, 291 00:20:19,000 --> 00:20:24,000 and so returning this allows us to do exactly that. 292 00:20:24,000 --> 00:20:28,000 If you look at how this code is written, we come across a problem. 293 00:20:28,000 --> 00:20:32,000 This code is all evaluated right away. 294 00:20:32,000 --> 00:20:37,000 We need to be able to access "#note-list-item-template" 295 00:20:37,000 --> 00:20:40,000 and if we look at how the code is included, 296 00:20:40,000 --> 00:20:47,000 the application code is evaluated before any of our HTML in our body is generated, 297 00:20:47,000 --> 00:20:49,000 including our template here. 298 00:20:49,000 --> 00:20:51,000 So as we run it, it's not going to work. 299 00:20:51,000 --> 00:20:58,000 This is a huge problem I came across, and it was tough to figure out a solution. 300 00:20:58,000 --> 00:21:02,000 Basically, we need to defer a lot of our application code 301 00:21:02,000 --> 00:21:07,000 until after we've generated all of our actual code, 302 00:21:07,000 --> 00:21:11,000 so we need to run our Backbone code so it can read out the database 303 00:21:11,000 --> 00:21:17,000 and generate dynamic pieces of information before jQuery Mobile does its thing. 304 00:21:17,000 --> 00:21:21,000 The problem is jQuery Mobile will try to execute immediately; 305 00:21:21,000 --> 00:21:24,000 there's no good way to defer it--at least in this version. 306 00:21:24,000 --> 00:21:30,000 So where this becomes a problem is let's say we're on a page that is for a specific note. 307 00:21:30,000 --> 00:21:33,000 Let's say we're looking at note #1. 308 00:21:33,000 --> 00:21:37,000 Well, when we load the page in statically right here, 309 00:21:37,000 --> 00:21:42,000 the div with the id of note 1 does not exist. 310 00:21:42,000 --> 00:21:45,000 But as soon as Backbone loads and we do our magic 311 00:21:45,000 --> 00:21:50,000 which we'll write a little bit later, it's actually going to generate the code to create the page 312 00:21:50,000 --> 00:21:52,000 for note #1. 313 00:21:52,000 --> 00:21:55,000 So the problem is jQuery Mobile is looking for note #1 314 00:21:55,000 --> 00:21:59,000 before Backbone has a chance to actually create that page, which creates an error. 315 00:21:59,000 --> 00:22:04,000 So basically, we need to be able to call all of our application code 316 00:22:04,000 --> 00:22:09,000 before we call jQuery Mobile, so if we move jQuery Mobile 317 00:22:09,000 --> 00:22:12,000 to the end, that's all good, but we still have the problem 318 00:22:12,000 --> 00:22:16,000 of we want to be able to do things in our application, 319 00:22:16,000 --> 00:22:20,000 like read in the template right here 320 00:22:20,000 --> 00:22:23,000 and still have it execute before jQuery Mobile. 321 00:22:23,000 --> 00:22:28,000 Now, one thing that you might think we could do is take all of our application code 322 00:22:28,000 --> 00:22:33,000 and wrap it in a document.ready function like we did for this snippet of code, 323 00:22:33,000 --> 00:22:37,000 but the problem with that is if we call document.ready, 324 00:22:37,000 --> 00:22:42,000 all of our code is going to load after the jQuery Mobile code loads. 325 00:22:42,000 --> 00:22:44,000 So again, we're going to run into that problem. 326 00:22:44,000 --> 00:22:47,000 Now, the best way I was able to figure this out 327 00:22:47,000 --> 00:22:51,000 is we actually need to rely on the way scripts are loaded 328 00:22:51,000 --> 00:22:57,000 and at the very least, move the script tag for our application in jQuery Mobile 329 00:22:57,000 --> 00:23:02,000 to the very end of the body. 330 00:23:02,000 --> 00:23:08,000 Now, generally, I don't like to do this because it's going to lead to a flash of unstyled content 331 00:23:08,000 --> 00:23:12,000 when we first load up until the application code is able to run, 332 00:23:12,000 --> 00:23:15,000 but it's an evil that we can get away with. 333 00:23:15,000 --> 00:23:18,000 Now, for simplicity's sake, I'm actually going to move all of our script tags 334 00:23:18,000 --> 00:23:20,000 to the bottom of the page 335 00:23:20,000 --> 00:23:24,000 because we can solve all of the other problems simply enough. 336 00:23:24,000 --> 00:23:29,000 So in this case, now we have all of our scripts at the bottom of the page. 337 00:23:29,000 --> 00:23:33,000 In our application, we'll have the ability to target through jQuery 338 00:23:33,000 --> 00:23:36,000 any of these script tags or DOM nodes 339 00:23:36,000 --> 00:23:41,000 without having to wait for document.ready. 340 00:23:41,000 --> 00:23:44,000 So if we go back to our application.js, 341 00:23:44,000 --> 00:23:49,000 we could actually remove this document.ready right here 342 00:23:49,000 --> 00:23:52,000 because we no longer need to wait for the document to be ready 343 00:23:52,000 --> 00:23:55,000 because by the time our application.js is called, 344 00:23:55,000 --> 00:24:02,000 we should have defined our new div here, so we'll be able to use jQuery just like that. 345 00:24:02,000 --> 00:24:06,000 So all of this code will run before jQuery Mobile even knows what's going on. 346 00:24:06,000 --> 00:24:12,000 We'll see the specific example of when this is important when we create the detail of use 347 00:24:12,000 --> 00:24:15,000 for our notes and see how they are dynamically generated, 348 00:24:15,000 --> 00:24:19,000 but for now, we're going to apply this code because we want to be able to use 349 00:24:19,000 --> 00:24:25,000 the jQuery function right here as well as the jQuery function right here, 350 00:24:25,000 --> 00:24:27,000 so now by the time this code runs, 351 00:24:27,000 --> 00:24:35,000 the "#note-list-item-template" will be on the page and accessible. 352 00:24:35,000 --> 00:24:38,000 And so now we've defined collections and Views. 353 00:24:38,000 --> 00:24:41,000 We've done a lot of code without actually testing it, 354 00:24:41,000 --> 00:24:45,000 so it's going to be interesting when we go to refresh, but now let's go ahead 355 00:24:45,000 --> 00:24:48,000 and first, create our collection. 356 00:24:48,000 --> 00:24:50,000 Now, I want to store this under our apps 357 00:24:50,000 --> 00:25:00,000 so I'm going to create another sub-object called collections:{} 358 00:25:00,000 --> 00:25:14,000 and I'm going to say App.collections.all_notes = new NoteList(). 359 00:25:14,000 --> 00:25:18,000 So now that I've created our collection, I'm going to create the View for our NoteList 360 00:25:18,000 --> 00:25:22,000 which will use that collection as a basis. 361 00:25:22,000 --> 00:25:24,000 So now we're going to do App.views 362 00:25:24,000 --> 00:25:30,000 and we'll call this list_alphabetical 363 00:25:30,000 --> 00:25:36,000 and we'll instantiate a new NoteListView.({}). 364 00:25:36,000 --> 00:25:40,000 Now we're going to have to pass to this an element, 365 00:25:40,000 --> 00:25:45,000 and we'll remember our id is ("#all_notes"). 366 00:25:45,000 --> 00:25:55,000 If you look at our HTML, we can see that our ul has an id of "all_notes". 367 00:25:55,000 --> 00:26:00,000 We also need to pass in the collection. 368 00:26:00,000 --> 00:26:13,000 All we need to do is specify collection: App.collections.all_notes. 369 00:26:13,000 --> 00:26:19,000 Now, that's a lot of code, and let's see if this does anything right in our actual browser. 370 00:26:19,000 --> 00:26:25,000 So let's flip over and go back to our localhost here, refresh, 371 00:26:25,000 --> 00:26:29,000 and now we're getting some syntax errors, which is not unexpected, 372 00:26:29,000 --> 00:26:33,000 so let's take a look at application.js 118-- 373 00:26:33,000 --> 00:26:36,000 probably just missed a comma-- 374 00:26:36,000 --> 00:26:38,000 I sure did. 375 00:26:38,000 --> 00:26:42,000 Refresh one more time; didn't get any syntax errors, so let's see what happens 376 00:26:42,000 --> 00:26:44,000 when you look at All Notes. 377 00:26:44,000 --> 00:26:47,000 All right! It looks like we actually have a list of notes here. 378 00:26:47,000 --> 00:26:53,000 We have My Note, we have the note for the one that I missed the title on, 379 00:26:53,000 --> 00:26:57,000 our Third Note, our Test, and our Next Test--these are all the notes we've been creating 380 00:26:57,000 --> 00:26:59,000 throughout our code. 381 00:26:59,000 --> 00:27:02,000 I'm not going to click on it right now, but you can see in the status bar 382 00:27:02,000 --> 00:27:08,000 is it's linking to note_e17 or the id of that note. 383 00:27:08,000 --> 00:27:11,000 So now we need to create the specific pages for each note. 384 00:27:11,000 --> 00:27:14,000 If I were to click on it, we're going to get an error loading page, 385 00:27:14,000 --> 00:27:19,000 but that's because we need to now create pages for jQuery Mobile to actually dig into.