Though some of the concepts in this course are still relevant, overall this course does not reflect our current course standards or industry best practices.
Table of Contents
How We Got Here
Introduction
Sam gives a brief introduction and schedule for the session JavaScript has followed an unusual road to get where it is today.Backbone Dependencies: jQuery
The DOM is a mess. Backbone depends on jQuery because jQuery is a DOM library and great for manipulating DOM elements.jQuery Review
While jQuery gives developers a consistent API for DOM manipulation and routines like AJAX, it's not a tool for organizing and managing applications.Backbone Dependencies: Underscore
Underscore is a utility library. It includes useful utilities for Objects, Arrays, Functions, etc.Single Page Applications
When approaching single page applications, developers want to remember the experience should mirror that of a traditional web application. For example, including bookmarkable pages/states. A solid understanding model-view-controller principles helps clarify the process of taking server-side MVC techniques and moving them to the client. This transition introduces the concept of a model-view-presenter architecture.Philosophy, usage, and convention
When using Backbone, there is often more than one way to implement a system. Backbone attempts to remain agnostic leaving many of the patterns up to the implementers to figure out. Sam begins with a some jQuery code that displays a list of comments when a "show comments" button is clicked. Since it's writing with jQuery, it's coupled closely with the DOM. There are a number of other issues as well.Core Backbone Components
Backbone consists of models, collections, custom events, sync operations, and views. It works best with a RESTful architecture and if you're willing to do thing the "Backbone way".Prototypal Inheritance and Extension
Since JavaScript currently lacks a "class" keyword, subclass are created by extending Backbone core components are essentially the constructors and the instances are objects created by using the "new" keyword. Constructor and initialize behavior can be overridden in every Backbone class. Constructor functionality is the first code to fire when an object is instantiated. Initializing code runs after all constructor code has completed. The event system is baked into all Backbone components. It's a synchronous system where event handlers will be called immediately after an event is triggered.
Overview of the Comments Application
Comments Project Setup
The project file can either be view on jsBin or by cloning Sam's GitHub repository. Sam begins by describing the setup and functionality of the application. Sam also gives a quick overview of the code structure.Comments Model, Collection and View
The comments Model will represent the data and help with validation. The Collection represents a list of Model objects. The View will display the collection in the markup.Comments Application View
The overall comments application will have a Backbone View responsible for the entire comments section. The element for this view is going to be the ".comments" class. This allows for a very flexible design and reusability.Summarizing the functionality
A Backbone collection's add method receives a model object. This triggers the render method for that model's view. All functionality is globally declared inside a single JS file. Later, Sam will demonstrate a better architecture.Comments Application Audience Questions
While answer a question about model objects, Sam demonstrates some debugging techniques and the debugger keyword.Comments Project Setup and Dependencies
Sam prepared a blank starter project tin the project-template branch of his GitHub project. Sam also introduces a few third-party libraries he recommends during development including RequireJS, Bower, and GruntAdvanced Feature Demonstration
This, more robust, comments application now has a login system, ability to edit/delete comments, and a "Zen interface" for adding comments. Sam will be diving into these advanced features and how they were implemented with Backbone.Code Walkthrough
The main.js file is the entry point for the application. From there, RequireJS includes the necessary dependencies and wires up the application. Sam also demonstrates the templating system within the views.Additional Code Features
Sam introduces a few additional topics that will be live-coded later in the course. This includes a more robust validation system and an AMD module examples. Sam field a few additional ES6 questions during a brief break as well.
Backbone Models In-Depth
Models In-Depth
As covered earlier, Models represent a single resources from the server and are useful for storing data in-memory within an application. Models can be made flexible with helper methods like parse, toJSON, and sync.Model.parse & Model.toJSON
The parse method gives developers the opportunity to manipulate data as it's returned from the server. This could be used for simply formatting the returned data or creating additional model objects. The toJSON method does the inverse of the parse method. It allows developers to add omitted model objects back into the prototyped toJSON output.Defining Models
When defining models, data structures do not need to be predefined. However, predefining attributes allows developers to set default values. The "on" method can be used to add listener events for Model attributes. Models also have methods like "save" which enable persistence on the server.Using RESTful APIs
REST is a way to architect data and a means for traffic to act on that data. Backbone works well with REST APIs for data communication. Sam fields an audience question on why "listenTo" is preferred over "on".Live Coding: REST APIs
Using Mozilla Persona, Sam begins coding a model object that will communicate with the Persona APIs for managing login information. Setting the URL property within that model is the first step in the communication.Persona Questions
Sam addresses some audience questions regarding the personal integration including how to set up persona with the course files.
Backbone Views In-Depth
Views & Templates
In Backbone, views are really versatile. They are simply an object that represents the presentation of a model so they can adapt to many MV* patterns. Templates are included in view objects. Backbone will work with any templating library because all Backbone requires is an HTML fragment. However, including templates inside a script tag can be expensive.Rendering Templates
Including templates in individual files moves them from the DOM and into a middle-ware pattern. This is because module loaders like RequireJS can better optimize your templates in production. The primary use of templates to get away from concatenating long strings of HTML. They also make rendering views easier.DOM Events and Memory Management
The events hash in Backbone is similar to using jQuery's "on" method. Garbage collection happens automatically in JavaScript, but destroying views with the "remove" method can aid in memory allocation. Sam discusses why using the "listenTo" method when adding events is much better than using "on" for garbage collection.Responsible Rendering
Solid application design means applying the single responsibility principle and interface segregation. Also, organizing your application around a view allows for more reusability and a more modular approach.Views Audience Questions
Sam addresses some audience questions on using views versus routers and also on lazy loading data.
Backbone Collections and Routers In-Depth
Collections
When creating collections, you are able to pass a single model or an array of model objects. The models property within a collection give you a number of useful methods for working with the data. Collections also have a number of useful methods for adding, and removing data. These methods have additional parameters that can be useful when manipulating models within a collectionRetrieving Model Data
Methods like get, at, where, and pluck help retrieve model data from within collections. When you have access to a model's ID, using the get method is the most efficient method to use. There are a number of other Underscore aliases available within Backbone. This includes iteration methods, transforms, and many others.Syncing Data with the Server
The "url" property specifies a RESTful endpoint. The "fetch" method invokes the RESTful data request. Backbone's "sync" method is called every time model data is written or read. Overriding this method helps developers add custom implementation to every service call.Routing Background
Routing is the ability to look at a URL within a web application and recreate a state. Most client-side techniques use a hash(#) to determine a specific state. These routes are called hash fragments. Hash fragments have evolved into the HTML5 history API. This HTML5 history API enabled more advanced routing because full URLs can be used, as opposed to hash fragments.Backbone Router
Backbone routers are hash-maps that tie a specific URL to a function call. The URLs specified in the router use regular expressions for more complex formations. After all routes have been defined, calling Backbone.history.start will begin using hash-change routing to managing page-to-page navigation.Router Code Walkthrough
Sam walks through a routing example for a login scenario. The application contains routes for logging in, logging out and different authentication levels for each user.
Testing Backbone Applications
Backbone API Project Introduction
For this live-coding session, a jsBin project has been set up. Data will be pulled from the quickleft.com server. Sam gives a little background information on the code setup. Sam fields a few questions from the audience on architectures and managing larger applications.Testing in Backbone
Mocha is a JavaScript test framework running NodeJS and in the browser making asynchronous testing simple. However, Mocha doesn't contain an assertion library. That's where Chai comes in. Sam includes a third library, Sinon.js for running the test spies.Writing Tests
The most basic test developers can write is an assertion based on the application existing. Tests are typically much more specific that that, however. Sam demonstrates adding test cases inside the comments application and how to handle side-effects. Using the before identifier can allow variables to be declared and later reused inside individual test cases. The context keyword can be used to isolate a group of tests.Using Sinon.js
Sinon.js can be used to "spy" on methods or watch when they are called. Testing method call often triggers side effects. In that case, Sinon.js can be used to "stub" the method or block it from running.Testing Event Handlers
Testing event handlers can be tricky because they are reliant on the DOM. The best way to test them in isolation would be to either trigger the event or pass the event a mock-object. While debugging some of the testing scripts, Sam discusses a few troubleshooting resources for writing unit test including the Sinon.js documentation. He also discusses some drawbacks to consider when writing tests.Testing Views
When testing views, one important assertion is to verify the required model object is passed to the view when it initializes.Final Q & A
Sam answers a few questions on additional test-driven-development resources. Audience members describe a few of their experiences when writing tests for JavaScript code. Wrap-up