 So, I'm super excited to be here. I actually feel really at home talking about the backbone. So today we're going to explore the little opinions and big possibilities, tools and patterns for building large-scale applications. So this is actually one of my favorite topics to talk about. I feel like it's one of the least known areas of backbone and one that I see a lot of developers struggle with. I guess the introduction has already been made for me, but since the beginning of this year, I've been writing and producing screencasts for a site that I created called Backbone Rails, which basically focuses a lot on these topics, building application architecture. So, today we're going to be talking initially about why I think architecture and backbone is so difficult. And I'll show you some tools and patterns that I've used to successfully build some really scalable apps. And I feel because backbone has a relatively small set of tools and components, I feel like there's an unfair bias on backbone really only being suitable for solving really small problems. When I was looking and submitting a talk here to Backbone.com, I got really excited because the call for speakers emphasized utilizing backbone within a large application. So let's start off by exploring the definition of a large-scale application. And I mean, what do you think it is? Do you think visual complexity, like a lot of moving parts on the page? Perhaps you think maybe it's a really advanced data synchronization model, maybe real-time collaboration like with Google Docs. Or maybe instead, you know, you think in terms of size, perhaps a code base that reaches 100,000 lines is officially large. And Adios Mane in his paper on patterns for large-scale JavaScript application architecture says that in his view, large-scale JavaScript apps are non-trivial applications requiring significant developer effort to maintain, where most heavy lifting of data manipulation and display falls to the browser. He goes on to say that if working on a significantly large JavaScript application, remember to dedicate sufficient time to planning the underlying architecture that makes the most sense. It's often more complex than you may initially imagine. I certainly agree with all of that, but it's still pretty abstract. I don't feel like we're really any closer to really defining what it is. So I'd like to try to define some characteristics of backbone applications that hopefully point us in the right direction. So let me just first start off and just say, what is not a large-scale application? And I really wanted to use to do NBC here as the poster child, because it's unfortunately most likely the first backbone app that most new developers use to understand backbone or even compare it against the other different NBC frameworks. And if you're looking at two NBC trying to foresee what it's like building a large-scale backbone app, this pretty much couldn't possibly point you in a worse direction. And why? Well, so let's see. I mean, you can add some to-dos here, which creates additional rows and you can check them off and clear them. But overall, this is really just a single function app. It just does one thing. And the problem is that this doesn't even come close to modeling or reflecting even what most basic backbone applications need to do. I mean, for instance, there's no routing events, there's no page changes. That means there's no need to manage, like, view hierarchy, figuring out how to replace old views and bringing new ones in. And most backbone apps consist of many multiple pages. One of the first steps in organizing those is breaking those out into distinct modules. If we tried separating out everything into NBC, it would likely lead to a significant over-engineering, probably turn a lot of new developers away for lack of a better understanding. But I think this is a good starting point. So we've identified some characteristics that you don't see present in really small single function applications. So now let's raise the bar way up. And personally, when I think of ambitious applications that I've used, ones which are of sufficient size and scale, undavidably needing to follow solid design patterns, I think of applications like Ardeo, Google Analytics, WordPress, Pandora. While Google Analytics is the only one of these that's not actually built with backbone, I believe without a doubt that it could be built with backbone. And to me, it's probably the single greatest example of the power of a fully client-side application. And so when I sit down and I'm writing backbone apps and code, this is where I set the bar for me. But for today, for our demo product, for our demo app, the one that we'll focus on and come back to throughout this talk is actually gonna be Ardeo, the first one. So I wanna show some examples of what I believe Ardeo is a sufficiently complex and large-scale application. For those of you who don't know or have never used it, Ardeo is just an application that lets you play music through your browser, assemble playlists, and create a music collection. So in this screenshot, I'm looking at my collection of music. And this lists out all the artists and displays that list those songs currently sorted by artist's name. And I can of course change the sort of order to something different. So when I click Play Count, sort by Play Count, it only updates that one portion of the page. And I could alternatively filter by searching or just clicking on any artist from the list there on the left, which instead of sorting, it would just filter down those lists of songs. And Ardeo's some really intelligent guessing and caching based on how large your collection of music is. So after the first time that I sort this list of songs, if I were to come back to this exact same sort order, instead of making a fetch to the server for that data, it would actually just display the cached collection, which would make the UI appear really snappy. And so also note that every single change, though I didn't show it in this demo, every single change that affects the UI, such as changing the sort order or filtering or searching, Ardeo's manually going to use the push state to update the URL. So that means that if we were to hard refresh or open up that link in a new tab, we would actually be returned to this exact same state that we left off at. So that really means that two interesting things are happening is one that state of the page is actually gradually changing as we click different buttons and interact with the UI. But that there's also this other representation of that state that should be able to be rebuilt solely from the URL only. So far, we've just been updating that one portion of the page, but if we come over to the playlist over here on the left, and we click on any item in this collection, say, we click Pink Floyd, then the entire music collection, that main region is gonna be replaced, and we're given a loading spinner to indicate that we're fetching one or more dependencies from the server. And then when those are returned, then our page displays, and now it takes out that entire main region as our collection of music did. So we also go into our settings, and this just repeats the same process. We click settings, it changes out that main region, and there you go. So, we have all of these modules on the screen which are visually orchestrated together, but they're actually all completely independent from one another. Different UI events may replace only a small portion of the screen while others wipe the entire main region. And of course, we've only scratched the surface of RDO and completely left out the fact that it's playing music real time in our browser and synchronizing that across any other device that we have connected. But for the moment, our focus really is on just this UI. So after looking at RDO, I think we can put together some characteristics of large scale apps from pen to paper. We know that there is a strong likelihood that we'll be dealing with multiple, if not many routers. That means that we'll have to rebuild the state of our UI solely from just a routing URL. We'll also need to manage a significant amount of views from small or large state changes in the UI. So we know that we're gonna need a really great system from being able to nest and compose multiple views together within each other. And technically, we need to be able to make sure that we're cleaning up those old views, shutting them down, ensuring they're eligible for garbage collection, AKA no memory leaks. And we know that we should be breaking our application into independently smaller chunks and modules and that these different parts of our system would need to communicate based on a series of complex events. So when an important action happens in one part of our system, another part to be able to be notified about it. So we'll probably have to manage lots of state changes, right? And from my experience, there's a strong likelihood that you'll be dealing with a large quantity of entities. Which is actually the same word that Jeremy was using. And that's the word that I use to refer to either models or collections. These are a significant challenge to manage. I mean, knowing when to pull them from the server, when to catch them, and how to handle things happening in real time. I mean, in the backbone docs, it suggests bootstrapping all your data when your application initially loads. Really, that would only work for really small sets of collections which don't have a propensity to go stale on you. Like in a larger application, you're probably working with like over a hundred different URL endpoints for these models and collections. So really, we just have to be prepared for writing a literal ton of JavaScript files. And that's not hyperbole. In the last 12 months, I've literally personally written close to a thousand JavaScript files for a production application that I'm working on. And of course, when I say JavaScript, I really mean coffee script. So I think we've identified some good stuff here. But where do we go? Where do we go here? Admittedly, there's a pretty significant gap between simple to-do apps all the way up to something like Ardio. There's an abundance of good backbone tutorials and knowledge out there, but it's mostly like in the getting started space. It's pretty sparse in the intermediate or even the advanced areas. But that's okay because building architecture is really about understanding good JavaScript patterns. So let's dive into what those may be. And did you catch that? I mean, I said that really building architecture is about knowing and leveraging good JavaScript patterns. There's no magic or silver bullet that's gonna do this for you. I mean, we're talking about significantly sized, ambitious applications. We're talking about the propensity to have more JavaScript code than any other language in your stack. And so we really have to admit to ourselves that engineering this all together is pretty serious business. I mean, it's a challenge to all developers. So anything new or innovative and worthwhile these days is extremely unique and specialized in a particular niche. So of course, nothing out of the box is gonna do this for you, but I get it. You're frustrated. You've written a gazillion routers and views. You've read a few books on a backbone. Maybe you've watched a few screencasts, though not mine, else hopefully you're not feeling frustrated. You've got memory leaks everywhere and your code base is just really just awful to work with. It's not callback hell, but it's bloated backbone hell. You know, and I've been there and I've probably said the same thing. I mean, this can't possibly be my fault or your fault. It's just backbone's fault. I mean, backbone just sucks, right? So let's just scratch everything we've written and start all over with something else. We'll stop blaming backbone, embrace it. I mean, its philosophies are honestly really solid. And while I don't think that they're promoted well or understood, we can blame Jeremy for that. But when he pushed out version 1.0 of backbone, he wrote in his blog that the essential premise at the heart of backbone has always been to try to discover the minimal set of data structuring, models and collections, and user interface views and URL primitives that are useful when building web applications with JavaScript. In an ecosystem where overarching decides everything for you frameworks are commonplace and many libraries require your site to be restructured to suit their looking field, default behavior, backbone should continue to be a tool that gives you the freedom to design the full experience of your web application. I really think this is so perfect in pulling in and I'm a 100% firm believer in his sentiments. In fact, I believe the number one lesson that we should take from this is that if you're building a significant application, your number one priority should be to never give up control because you will need it. We've all seemed like a progressing shift and a good one from the days of monolithic tries to do everything for you frameworks to a much more nimble, simpler, focused set of tools. And I think this really reflects well in terms of building ambitious applications. Applications which are different, which have their own very specific niche and use case are all about creating an experience that's perfectly tailored to that environment. And really in order to do this, it almost always means assembling the tools that are exactly right and perfect for you. The great thing about backbone is that we have an unprecedented amount of tools that fit this philosophy perfectly. So we should leverage every aspect of this ecosystem. When we have a vast ocean of resources and plugins, extensions, we don't have to reinvent the wheel every time. So we can use something that solves one particular problem and does it better than anything else. And honestly, two-way data binding is probably the most overrated feature ever. Probably a special place in hell reserved just for two-way data binding. All right. So let's get back to application architecture, right? Because while each of those plugins and extensions solve one specific problem, they're still underpinned by our application's architecture. And unless we really solidify that we have a robust plumbing system, a structurally sound frame and a properly wired electrical system, trying to move in and add furniture and nice things in our house would just be an absolute recipe for disaster. So why is this the case? Well, let's take a look at what we get. We get routers, which listen to routing events and are also traditionally, strangely enough, used to manage views. We also get a lightweight event system. I've purposely left out models and collections here because those are actually very specialized objects. So they're the source of truth in your application and they're not really its architecture. Models and collections don't have responsibilities to any other object, just to themselves in their own internal state. So a large application, when we would just die trying to cram all of our code into these few objects. And why? Well, for one, we have like a ton of coupled concerns here starting with this router. So here's some code and it shows 10 routes, which is just a tiny fraction of the number that you'd expect to have in a large application. There's no way that one router could or should manage all of these. But let's just imagine for a moment that we navigate to the user's route, which would fire this list user's callback, right? And that by itself is okay. We're in the router, which listens to routing events. But the problems start here because traditionally, the router is also responsible for fetching dependencies. The right here, it's instantiating a new user's collection. It's also calling that directly, which is a terrible idea. And then it's also responsible for instantiating a view, pass it in that collection, and then determining even where in the DOM does this view should go. It also has to call methods on that view in order to get it there. This is, it's a trivial example, but it's quickly compounded and magnified. And this is where most backbone apps just go wrong. And it's clearly the very first step. And so remember, backbone is about the lowest common denominator of objects. And it's absurd to think that we should only use what we get. So what we'll need in order to build large-scale applications are much more specialized objects with much better separation of concerns. So here's what I'm suggesting. So all of these specialized objects I'm about to talk about are all connected. So I'm gonna first just introduce you to like the name of what each does and kind of a little bit about it. Then we're gonna go into like a deep dive and I'll visually demonstrate the usage of how to use each one. So right, we need to create a lot more hierarchy within our specialized objects and assign them very specific roles and responsibilities. The first thing that we could really use is like an actual application object. This guy will basically act as the container for all of our application-specific code. And that's basically everything minus third-party libraries and stuff that's not just used in this one specific application. So everything hangs off of this object, right? You'll get its own startup and shutdown behavior and it will also act as a great place to store objects that you essentially want globally accessible to all of your modules within the app. But you don't wanna actually make those like global objects on the window. A common use case would be like passing in like a current user, like the logged in user from the server. You're gonna want him like accessible to everything and storing him on the application object and giving like a handler and interface a way for other modules to access that is really a great idea. Application object is also where we're gonna set up like our main like structural regions that we'll insert all the other views into. We'll get more into that in just a second. The next part, the things like immediately beneath the application would be app modules which contain all the code that are the actual user-facing parts of your application. So this is actually where we'll move our routers into. And app modules also consist of all of the controllers and the views which actually make up the UI. So in this way, they're like the gatekeeper for these resources. They're the sole authority for all of the things within the controllers and the view. So like in Ardeo's example, we probably have app modules for like artists, album, album comments, playlist, playlist songs, currently playing, settings, billing, settings payments, settings profile, all of those kinds of things. They're all broken out into their own specific encapsulated modules. All right, so as I said, your app modules contain one or more controllers and your controllers are built in like a restful style. So controllers really are the end of becoming the workhorses of your application. They're the ones that are orchestrating all the business logic and all the application workflow. Really the controller is directly responsible for instantiating all the views that's on the page within its scope, within its concerns. And that those views are given all the dependencies they need, such as like their entities, their collection models, all the things that they need in order to function. All right, so we have specialized view now, not just regular vanilla views. And by doing it this way, now your views and separating out all the concerns and splitting them out into other objects, now your views are just back to, well, just managing the view, just their assigned template, a small chunk of the DOM, a portion of the page. And except we've specialized them, given them certain abilities in order to automate their management, right? Since we need to compose like a visual hierarchy and we need to establish like a pecking order, these specialized views are built to automate cleanup and shutdown, which we'll get more into in just a second. So really it's just this. I mean, this is really just the chain that makes up like application specific code that builds your UI, your interactions, your logic, your events and all that jazz. But we do have some other objects though. And while each of these has its own different role and responsibility, they're really all part of the utilities of your app. They're like this, they're the shared objects that any of your application specific modules can call out to and utilize. So we've got components, mix ins, entities and config. So components, first off, are kind of like services in Angular. Like they have their own controller and usually their own view. And common examples are basically where you wanna take specialized behavior out of views and abstract those up into their own reusable components. You can decorate views and basically give them this behavior with like a clean interface between these two things. So like a common use case would be like forms, loading views, grid views, uploading views, things like that. Mix ins, mix ins are a way to basically just group code that you want mixed into your views really like low level stuff for like DOM manipulation, things like that, which we'll get a little bit more into. Entities we already talked about. Entities are basically just the shared namespace for essentially all of your models and collections. It wouldn't make sense to like, even though we might have like a user's module, it doesn't make sense to store like the user entities in there because we might have like a dashboard module that shows user or an admin module that shows users. So by splitting it out and separating it, putting in its own namespace, that all of the other things can call out to those entities. Then we have just your basic config, right? Just the configuration like the overrides for backbone or anything else or configuration for plugins and stuff that you've brought in, all right. So we also have, I mean, we've been talking about it, but we have this actual specific notion of a module which is like a namespace, a grouping of specific behaviors, specific objects that have us, certain sets of responsibilities. And pretty much the last thing that we have is like a messaging bus for requests, commands and pubs of. So even though we have lightweight events in backbone, the messaging bus is basically the thing that it moves those responsibilities into the application. And instead of calling things directly, you'll go through this. All right, so this is where the fun starts and I'm gonna go through visualizing each one of these. So we have our application object which is like the ultimate container. Everything hangs off. Everything hangs off of, right? So the circles on the left would be like app modules. Those are the things that are on the application that are specific user facing. And the stuff on the right is like the shared utilities and these components mix in, config, stuff like that. This will hopefully give you a better idea of what I meant by application regions. So like this is an example, if you have, you can set specific regions on your application that essentially all the other views will go into. Like an audio, we probably have a header, a footer. We have like that aside, which is like where our playlists and stuff go and even like the current playing. So we probably have like five different regions for there. As I mentioned, like having an application instance is a great place to store entities and resources that you want globally available to all the other modules. All right, and next up we have the app module. And the app module really contains one or more controllers and all these controllers are built like in the restful style. So you only have like one list, one show, one new controller. Optionally, if we want the app module to be roundable, it would have a router. If not, it wouldn't and that's totally cool. And this is basically where you would actually put all of the handlers. None of the things inside the app module are directly accessible. You have to go through the app module to actually request those objects. So that's where you would put all those definitions. A visual example of this would be if we had users, admin users, dashboard users. Those are three different app modules. And each of these has their own controllers that they're directly responsible for. They're the sole authority of those. And they're not directly accessible. And these things, that module calls in and instantiates those controllers. And the way that that happens is through routing events. Like traditionally we navigate to users or users ID for the show, users new. So that's a way that an event would happen. Users module would instantiate those controllers. Or it could happen through requests and commands that I just talked about. But nevertheless everything goes through the actual app module. Nothing talks directly to those objects within it. So next up we have the controller. And the controller really now is the visual composer. Its sole responsibilities are to all of the views within its scope within the thing that it's supposed to be managing. So let's talk about controller concerns because it's super important. Most of the code that you will write is honestly in the controller. It is very procedural. So it gives life, it creates new views. So that's obviously an instance of a layout. Creates this layout, stores this over here. And it understands view dependencies specifically. So basically it knows that while this view needs this collection or this model, then it would make requests to another area of the system. It would get back that instance and store it. It listens in response to view events. So like in this case, it would be listening. And actually backbone events are traditionally actually mixed into the controller. So here this scope is actually the controller instance. So we're really saying the controller is listening to the layout. Specifically it's show event. And then it's passing in a call-back list users. And basically we're saying, hey, when our layout gets rendered into the page, then we want to actually create a new instance of a collection view and then passing in that collection that we had requested earlier. So this is the mediator, the true mediator where it's dictating where everything goes and all that stuff. So now we have that collection view and that user's collection. Now we have to tell it where to go. So in this case, we want to insert it into the layout's user's region. And so we do all that in the controller. Controller also needs to understand the shared modules, like the components and stuff that exist outside in our system. So this is what I mean by basically like if we have an item view, a regular view that's sitting out here, but we want to decorate it with certain abilities that we've wrapped up in another object, a reusable component. Then the controller would really do that, it would say, all right, we're going to take this view and we're going to give it the abilities of this form. I'm going to mediate between those two different APIs. And so now we've decorated it. And often, sometimes views don't even know they've been decorated, which is exactly the way that you want it. All right, so that's the controller. So back to our view. So now we've taken all of these other application concerns out of the view, which should have never been there. Now all it has to do is just manage one thing. The thing that it's really good at, just managing the template, the DOM. And basically, views are just completely transient. They can be blown away at any time. And so one of the ways that we can handle this is by standardizing its methods and give them like a set that relates specifically to its lifecycle. So this gives us events and methods which articulate exactly where this view is at. So this is like a really natural way of tapping into these events and methods and controlling the behavior of the view and its templates. And it's so just obvious to look at this to know where you would need to put certain view-related code at, specifically to how it affects the DOM. It's a pretty straightforward. So here's an example of what a view should really look like. I mean, there are sometimes just only a couple lines of code. Right there at the very top, we have that mix-in. I'm not really going to go into mix-ins a lot, but this is kind of like a declarative way that when I'm talking about mix-ins, I'm talking about giving them traits and mixing in those traits, and then automatically handling collisions and stuff on methods. But really, like your methods are really just become the places to store view-related behavior in its lifecycle. And it just makes sense. I don't even really have to explain this. So one of the things that would never pass a code review is we should no longer ever be doing this, no longer ever instantiating an entity or a model directly in the view. That's something that should go on the controller and the controller should pass that specifically into the view. Also, this is instantiating it and calling it directly, and that's a terrible idea. So don't ever do something like this. All right. So we talked about the notion of having specialized views. So I've kind of already used them because all of these are connected. But we have an item view, which is typically paired with a model, which basically just has one thing passed in and it doesn't really have a lot of specialized behavior. We have a collection view, which if it's given a collection, it would automatically iterate on all the models in that collection, automatically instantiating other item views. So it basically gives us the ability to create a list, which is what we're doing all the time. Then we have a layout, which the little gray regions on this guy are actual regions and then any view can go inside of there, even other layouts. So you can have layout, layout, layout, collection view, item view, layout, and then just keep going. And it's basically like a Russian doll to where if you close out one view, higher up the chain, it's gonna automatically iterate down and close out all the other ones. It's gonna cascade. So that gives us like how we can automate, clean up and stuff. And it goes all the way back to having like application regions and stuff. If we're wiping out the main region, then every single view that's been composed in there is automatically gonna be cleaned out. So that's really cool. So now really all the view, we're talking about it's being responsible for the template, it's got methods and stuff, but all it's really doing, it's just listening to events that are being emitted from the DOM, whether it's click, blur, submit, focus, whatever else. And then all it's saying is it's not dictating anything off of that. It's basically just saying, hey, this happened. And whatever is listening to it, like the controller, is then responsible for saying, oh, when this event actually happened, then we need to do something in our application. We need to notify another area or call a method on a mall or something like that. So views have been grossly simplified and that's a wonderful thing. They're really just about getting the right properties into the model. And really a lot of these, if you're using a view model, instead of doing that in the view, you could even have this in another testable area of the model if you wanna have custom computed properties and things like that. So there's many different uses here. All right, so we've talked about a lot of things and it's kind of like, wow, this is a lot, oh my God. How would I ever be able to build this? But really if we go to just backplug.out.com, which lists out all the plugins for backbone, really what we're talking about here is marionette, right? It's the number one listed here by the amount of stars on GitHub. And this is pretty much gonna bank in all these specialized objects that we've been talking about. Marionette's very composite, so you get all these nice new toys and stuff, but you're not forced to use all of them. It's all, they're all completely split up for one another, which is really cool. But even with marionette though, you still just get these specialized objects, but it's up to you to decide like how to assemble all these things together to make sense of an architecture. So all the things that I've been talking about are ways to use these objects and stuff with a couple extra things like components and everything. All right, so let's talk about this messaging bus in depth. So we all completely understand what it is I'm talking about. So we have this situation here where we have a controller needs to reach out into another area of the system and it needs to get back a new instance of a user's collection. So what's actually really happening is something like this, right? We have, like this is just like a diagram of our model. We have our app modules on the left, so like users or nodes. And then like the controllers list show new, list and new, and then entities, which is part of like our shared utilities way over here. So what we wanna do is something like this. That's why it doesn't make sense to call these directly. And it doesn't make sense to store those inside of just that one module when user entities could be used by anything. But we have this notion of this new messaging bus which gives us the ability to do this, to be able to indirectly call something. And this is actually a really incredibly powerful concept. So I wanna give you an example here. The code on the top is like actually from our list controller. The code on the bottom is, it would be like the actual implementation of our user class. So right here in our initialized method inside of our controller, which isn't really that important, that's incidental. Well, right here we're actually requesting the user's instance. And so at the bottom, what we have is we actually have the handler for that defined right in the entities module. And this is the thing that basically you're creating like an interface too. Like it's responsible for understanding like what this command is. And it's responsible for understanding the implementation of the classes. If you actually look at this closely, we've written this very cleverly. We actually haven't exposed the user's class or the user's collection class publicly. Like these are actually not accessible to be called directly. But by adding the handler in line here, then this is in scope to the handler. So it's able to actually know what you want and be able to call into the classes and stuff and manage them. And this is like exactly what you want. So you can just change your hand alerts or you can change the implementation details of your classes by having to update any other aspect of your page. So these are completely decoupled, right? So what we've ended up creating is basically like an interface around all of our other objects. And everything has to go through this like standard way of requesting instances or commands, things like that through the system. And this is basically given to us by this application instance. In fact, all of these commands are actually set on it. They're registered. All right. So let's talk about folder organization because I can see maybe this is probably a little confusing, still a little abstract, kind of throwing a lot of things out here. This is kind of where it all comes together. So we have this folder organization, typically a root backbone folder. We have the app.js file. This is where you would define that application instance. This is where you would start up your, I'm sorry, you would start it up like in the server, but this is basically where you'd set up like all of the application instance stuff right there. And then you'd have like this apps directory. And the apps directory is where all of your working like app modules and stuff go into. So all the user facing things. Then everything else are just like siblings. And those are all the shared like utilities, config entity components, mixins, maybe base classes. It's usually smart. You're gonna override some base classes and extend everything else from. So all that would be stored there. So let's pull out this apps folder for a second and look at it in regards to Ardio. So Ardio would probably have like these apps folders for playlists, playlists, songs, album, album, comments, currently playing. So what I wanna focus on are these three, playlists, playlists, songs, and currently playing. So let's look at, see how these work together. So we're here where like on the settings page, right? But what I'm looking at right here is this playlist module. So this is a playlist app module list controller. So that's where the playlist dot list comes from because all that this thing is doing is just iterating on a collection of playlists and listing them out, right? So now, what if we want to create a new playlist? Well, we click this little button right here and we get a dialogue that pops up. Well, so this would be the new controller for the playlist and this would be responsible for putting this view together, probably pulling a component for the form. So we have like all the shared form component behavior. So that's what this is. So that's an example of how you'd have a new controller for that, right? So we'll keep going. So now I'll look at like actually clicking an item in our playlist, so we'll click pink load again, right? And so now this page is the actual playlist dot show because why we're showing one model in that collection. And specifically that's what I'm talking about. These are like the additional details for showing just one entity in a collection. And of course we have an edit button, right? So really the same situation here, dialogue pops up. Now this is the playlist dot edit. So all of these are independent but they're connected. They're connected to this like one like ultimate resource which is the playlist, the app model. And then really like the complicated thing here that's fun to explain and kind of like the Eureka moment for a lot of developers is really like this list. Like we have this secondary list that's kind of part of this playlist and what this is is basically you have a collection of playlists, you have models on each one and then this is an example of a nested collection within those. And so we've already defined our playlist dot list and this forces us to now instead break this out into a second module. And the context is playlist but this would be like playlist song. So this other area of the page is in a completely different module. They're just visually orchestrated together. And now this list, this playlist songs out list still just is dealing with one collection. It's only ever dealing with like a top-level collection. And if you have nested stuff, you just break it out. So I mean, it like literally works perfectly. So just the last one here, we have like the current playing dot show. That's what this would be, right? Cause it's showing one song that you're currently playing. And if we click to expand this, you know, now we have like a whole list of things that would just be the current playing dot list controller in that module. So all of these things like really, really work completely well together. In fact, I haven't come across a single situation where you cannot just break everything out into these. So just to show you, so now we've kind of gone back to our folder structure and now like our top-level route now is like app. So we kind of like drilled into that. And so like these three things would be the different app modules, right? And specifically these files are the app module definition. So that's where their router would have been stored. If they're routable, that's where like, how they instantiate the controllers is stored and like handlers for accessing those controllers is stored in there. And then all these folders just contain the controllers, the views and the templates specifically to like what I just showed. So like play list, list show, edit new, play those songs, just the list right there and currently playing. And you would have used like app commands and stuff, for the playlist to communicate with playlist songs, it would have had to have shared like a region of its layout and it probably would have used a command there to basically give access to that region and it would have passed it in that local instance for the layout stuff. So all these things really can be perfectly like coordinate together. So there's a lot of things like we haven't talked about today but hopefully this is kind of like a step in the right direction towards architecting your application. These patterns have worked extremely well for me. So that's it. Anyone have questions? Yes, we do. How do you connect all the views and modules and models and your application? Do you use like requireJS? That's, there's a lot of different ways that you can do it. You can use commaJS models, requireJS. You can just use lightweight modules that come with marionette. That's kind of like incidental. Like as long as you can bundle them up however you want and load them in whenever you want, as long as those handlers and stuff are defined when they're supposed to be defined, then everything will work as is. So that's kind of like that doesn't matter but I've used all three essentially. We have a Rails app. So we use like the asset pipeline which basically handles like the load order of the modules and I actually use headJS rather than requireJS without all the overhead to basically dynamically pull in entire modules when like routing events happen. So when a routing events hits, it will actually pull in like all the module level code. So the UI is only ever pulling in like what you've actually navigated to. Hey, Brian, you said data binding is from hell. Can you just elaborate on that just a little bit? Well, so I guess, you know, it's kind of like always like the whiz bang demo of like, oh, this framework is amazing. Let's just use data binding like, let's just use it everywhere. Why wouldn't it make sense? And you know what I've seen is just like, when we're talking about really granular control of our application, like you can't just like throw data binding at it and expect like everything to just like fall into place whatever you usually need a lot more sophisticated level of control. And I mean, I've used data binding. I can't say like plenty because usually like if you're, if you like architecturally split everything out like into little views and stuff, you really don't, you know, it's usually mostly used like when you have like a massive view and you have so many different concerns, you need to use data binding to basically like go in and only update one part of the page. But if you split everything out into smaller views anyway then you can just kind of like, just tell a view to re-render. So it's almost kind of like to me, it's like a, you know, a giant hammer and it has its use cases, but it's very specific. It's not like an all purpose tool at all. Hey, Ryan, how do you handle with the Marriott modules the automatic starting and stopping if you have multiple modules and you don't know which one might be handling just like something else and you don't necessarily know at the outset what modules currently open. Right, right. There any pattern for that that's kind of prevalent? All right, so I think, I think that question really is actually two concerns. There's the actual technical startup and shutdown of modules, which modules in Marriott, Marriott app modules specifically have the ability to be started up and stopped. And then you can have like events and stuff injected into windows happen. By default, they're started. And to me, honestly, I haven't had a lot of use out of just stopping them. But I think really what you're asking the second concern of your question is just like how do you orchestrate visually like, you know, a module coming in and like eradicating like the previous view and doing a knock like their technical startup and shutdown. And that's really just comes down to like the application regions. I mean, the clever way that Marionette has figured this out is basically views get blown out by other views. And so if you insert, you know, if we have a navigation like users and dashboard or whatever, and we click between dashboard and we then we click to users, the main region is gonna get blown out from the previous one and the new one's gonna come in. The way that I do it is I basically work off of those close events. So like my controllers bind to a top level layout. And those controllers listen to the layouts close event. And therefore I know that basically that this has gone away and I know it to do shutdown and stuff. So it's kind of like in reverse. We actually know, we have a system, a mechanism for knowing when views are closing down. And from there I listen those cascade all the way up. And then so that's how I would do it. Thanks for the talk. I just had a question about maybe reusing views in the directory structure you showed. It looked like they were quite specific to the app section. But in the demo, like the playlist track listing there, very similar to now playing track listing. Yep. How would you structure those things so you're not copying the case? Right, so it's not, I think that's more of a question of, I wouldn't like reuse the view instance. I would reuse the view behavior. And the behavior can be composed like in traits, like in mix-ins that you basically mix into all of your views or you break out the shared behavior view into a component. And then you're basically taking a vanilla view and you're decorating it with all this new behavior. So it doesn't, the instances don't matter. You don't have to keep up with those. You don't have to manage the state of those. We just have to take out and extract what they're really doing and then compose those or mix those in. So like gang of four, you know, like composition over inheritance.