Permalink
Browse files

Now try a elements

  • Loading branch information...
1 parent ee3dfb2 commit 6e465eccbd68159a0253628e0191c7142394d1a0 @molily molily committed Feb 26, 2012
Showing with 18 additions and 18 deletions.
  1. +18 −18 README.md
View
@@ -25,7 +25,7 @@ Chaplin is an example architecture for JavaScript applications using the [Backbo
* [The Cast](#toc-cast)
* [The Producers](#toc-producers)
-## <span id="toc-key-features">Key Features</span>
+## <a name="toc-key-features">Key Features</a>
* CoffeeScript class hierarchies as well as object composition
* Module encapsulation and lazy-loading using RequireJS
@@ -39,7 +39,7 @@ Chaplin is an example architecture for JavaScript applications using the [Backbo
* A collection view for easy and intelligent list rendering
* Client-side authentication using service providers like Facebook, Google and Twitter
-## <span id="toc-motivation">Motivation</span>
+## <a name="toc-motivation">Motivation</a>
![Modern Times](http://s3.amazonaws.com/imgly_production/3359809/original.jpg)
@@ -51,7 +51,7 @@ Chaplin does not intend to provide an all-purpose, ready-to-use library. It’s
This repository is a snapshot of our ongoing efforts. We’re evolving the structure of moviepilot.com over the time and we’re using Chaplin as a testbed and playground. Of course this architecture is not flawless. In fact there are several open issues so your feedback is appreciated!
-## <span id="toc-technology-stack">Technology Stack</span>
+## <a name="toc-technology-stack">Technology Stack</a>
For simplicity reasons, Chaplin consists of plain HTML, CSS and JavaScript. However, the JavaScripts are originally written in the [CoffeeScript](http://coffeescript.org/) meta-language. Most `.coffee` files contain CoffeeScript “class” declarations. In this repository, you will find _both_ the original CoffeeScripts and the compiled JavaScripts. So there is no need to compile the CoffeeScripts in order to start the demo.
@@ -79,7 +79,7 @@ Since this example isn’t about building and deployment, it has no such depende
r.js -o name=application out=built.js paths.text=vendor/require-text-1.0.6 baseUrl=.
```
-## <span id="toc-example-application">The Example Application: Facebook Likes Browser</span>
+## <a name="toc-example-application">The Example Application: Facebook Likes Browser</a>
While traditional site login using e-mail and password is still around, single sign-on gained popularity. The example application features a client-side OAuth 2.0 login with [Facebook Connect](https://developers.facebook.com/docs/reference/javascript/FB.login/). Facebook is just a sample service provider. On moviepilot.com, we’re also using the [Google APIs Client Library](http://code.google.com/p/google-api-javascript-client/). We have experimented with [Twitter Anywhere](https://dev.twitter.com/docs/anywhere/welcome) which provides a client-side login but doesn’t support OAuth 2.0. (Moviepilot.com allows you to log in with Twitter, but it’s an old-school OAuth 1.0 server-side login.)
@@ -95,13 +95,13 @@ After successful login, your Facebook likes are fetched from the Open Graph and
Besides the likes browsers, there’s a second screen which displays some latest posts on the moviepilot.com Facebook page. This is just another controller in order to demonstrate the change between controllers with proper routing and cleanup.
-## <span id="toc-architecture-in-detail">The Architecture in Detail</span>
+## <a name="toc-architecture-in-detail">The Architecture in Detail</a>
The following chapters will discuss the core objects and classes of our application structure.
![Machine](http://img.ly/system/uploads/003/362/032/original_machine.jpg)
-## <span id="toc-application">Application</span>
+## <a name="toc-application">Application</a>
The root object of the JavaScript application is just called `Application`. In practise, you might choose a more meaningful name. `Application` is merely a bootstrapper which starts up three other core modules:
@@ -111,7 +111,7 @@ The root object of the JavaScript application is just called `Application`. In p
* `Router`
-## <span id="toc-mediator-and-pub-sub">Mediator and Publish/Subscribe</span>
+## <a name="toc-mediator-and-pub-sub">Mediator and Publish/Subscribe</a>
In this sample application we’re using RequireJS to load JavaScript files on demand. While a script might load another object it depends upon or a class (constructor) it inherits from, it normally does not have access to the actual instances. Most objects are encapsulated and not publicly accessible.
@@ -140,7 +140,7 @@ mediator.publish 'login', user
The second and all following arguments are passed as arguments to the handler functions.
-## <span id="toc-router-and-route">Router and Route</span>
+## <a name="toc-router-and-route">Router and Route</a>
The `Router` in this example application does not inherit from Backbone’s `Router`. In fact it’s an implementation of its own with several advantages over the standard Backbone `Router`.
@@ -160,7 +160,7 @@ Additional fixed parameters and parameter constraints may be specified in the `m
@match 'likes/:id', 'likes#show', constraints: { id: /^\d+$/ }, params: { foo: 'bar' }
```
-## <span id="toc-controllers">The Controllers</span>
+## <a name="toc-controllers">The Controllers</a>
In our concept, a controller is the place where a model and associated views are instantiated. A controller is also in charge of model and view disposal once another controller takes over. Typically, a controller represents a screen of the application. There can be one current controller.
@@ -212,15 +212,15 @@ define ['controllers/controller', 'models/likes', 'models/like', 'views/likes_vi
A typical controller has one model or collection and one associated view. They should be stored in the `model`/`collection` and `view` instance properties so they are disposed automatically on controller disposal.
-## <span id="toc-models-and-collections">Models and Collections</span>
+## <a name="toc-models-and-collections">Models and Collections</a>
We extended the standard Backbone models and collections with some new methods. `dispose` is the destructor for cleaning up. Our `Collection` also has `addAtomic` for adding several items while fireing a `reset` event, and `update` for updating a collection while fireing several `add`/`remove` events instead of a single `reset` event.
Using these `Model` and `Collection` classes, we create a hierarchy of CoffeeScript classes. Many child classes override methods while calling `super`.
Models and collections are Publish/Subscribe event subscribers by using the `Subscriber` mixin. We do not register their methods directly as listeners using `mediator.subscribe`. Instead, we use `subscribeEvent` which records the subscription so it might be removed again on model/collection disposal. It’s crucial to remove all external references to model/collection methods to allow them to be garbage collected.
-## <span id="toc-views">Views</span>
+## <a name="toc-views">Views</a>
Our `View` class is a highly extended and adapted Backbone `View`. All views inherit from this class to avoid repetition.
@@ -238,7 +238,7 @@ On moviepilot.com, `CollectionView` is one of the main workhorses. It’s respon
The current `CollectionView` implementation is quite simple and could be improved in many ways, for example with regard to filtering, fallback content and loading indicators. Nevertheless the `CollectionView` is an essential piece. Rendering collections on the UI would be painful without it since Backbone does not provide a clean mechanism to render collections.
-## <span id="toc-fat-models-and-views">Fat Models and Views</span>
+## <a name="toc-fat-models-and-views">Fat Models and Views</a>
Following Backbone’s design that models/collection can fetch themselves from the server or other stores, most of our fetching code is in the model/collection. On moviepilot.com, the actual API calls are located in separate modules, but the whole processing and updating logic resides in the model/collection. Model/collections may fetch themselves on initialization without receiving a call to do so.
@@ -248,7 +248,7 @@ As a consequence, our controllers are quite skinny. In most cases, they just ins
There’s no specific reason for this decision, it’s merely a convention on where to put fetching and rendering code – your mileage may vary.
-## <span id="toc-event-handling">Event Handling Overview</span>
+## <a name="toc-event-handling">Event Handling Overview</a>
![Dance](http://s3.amazonaws.com/imgly_production/3362020/original.jpg)
@@ -304,7 +304,7 @@ In addition, `delegate` automatically binds the handler to the view object, so `
This isn’t the best solution but acceptable for now since this doesn’t occur frequently in our application.
-## <span id="toc-memory-management">Memory Management and Object Disposal</span>
+## <a name="toc-memory-management">Memory Management and Object Disposal</a>
One of the core concerns of this architecture is a proper memory management. It seems there isn’t a broad discussion about garbage collection in JavaScript applications, but in fact it’s an important topic. Backbone provides little out of the box so we implemented it by hand: Every controller, model, collection and view cleans up after itself.
@@ -314,7 +314,7 @@ Before a new controller takes over and the user interface changes, the `dispose`
This disposal process is quite complex and many objects needs a custom `dispose` method. But this is the least we could do. In Internet Explorer, moviepilot.com gets slow and memory consumption rises after several module changes despite all these efforts.
-## <span id="toc-application-glue">Application Glue and Dependency Management</span>
+## <a name="toc-application-glue">Application Glue and Dependency Management</a>
Most processes in a client-side JavaScript application run asynchronously. It is quite common that an applications is communicating with different external APIs. API bridges are established on demand and of course all API calls are asynchronous. Lazy-loading code and content is a key to perfomance. Therefore, handling asynchronous dependencies was one of the biggest challenges for us. We’re using the following techniques to handle dependencies, from bottom-level to top-level.
@@ -346,7 +346,7 @@ As mentioned above, Publish/Subscribe is a powerful pattern to promote loose cou
The Publish/Subscribe pattern is the most important glue in our application because it’s used for most of the cross-module interaction.
-## <span id="toc-conclusions">Conclusions</span>
+## <a name="toc-conclusions">Conclusions</a>
![Ending](http://s3.amazonaws.com/imgly_production/3362023/original.jpg)
@@ -365,7 +365,7 @@ Apparently, other projects experienced the same Backbone shortcomings and took a
* [Thorax](http://walmartlabs.github.com/thorax/)
* [Marionette](http://derickbailey.github.com/backbone.marionette/)
-## <span id="toc-cast">The Cast</span>
+## <a name="toc-cast">The Cast</a>
This software was mostly written by:
@@ -382,7 +382,7 @@ With input and contributions from:
* Patrick Schneider (9elements) – [@padschneider](http://twitter.com/padschneider) – [padschneider.com](http://padschneider.com/)
* Luis Merino (Moviepilot) – [@rendez](http://twitter.com/rendez)
-## <span id="toc-producers">The Producers</span>
+## <a name="toc-producers">The Producers</a>
The architecture was derived from [moviepilot.com](http://moviepilot.com/), a project by Moviepilot with support from 9elements.

0 comments on commit 6e465ec

Please sign in to comment.