Building a single page app with Backbone.js, underscore.js and jQuery
andyet.net
andyet.net
* Do not store state in the DOM. You'll live to regret it when you need to represent the same model in more than one place at once, or refactor your UI.
* Events are the way to go, when connecting changes in the model to updates in the view. Ideally, models know nothing about what UI happens to be on the screen at any given moment.
* If you're going to be doing interesting business logic in the client, it helps to have collections (in this case, Backbone.Collection) with a richer API than JS arrays: filter, any, map, reduce, reject, include, invoke...
* Lots of little testable JS files for development, one minified gzipped file for production.
The one point I'm in disagreement with is: "Keep your models as simple as possible". In my opinion, client-side models really shine when they contain a large part of your important JS business logic, and you can use the same models in different situations to provide access-control, URL generation, data munging, etc.
For example, here's a list of some of the methods we have on a Backbone.Model called "Document": viewerUrl, publishedUrl, canonicalId, openViewer, openText, openPdf, allowedToEdit(account), checkAllowedToEdit(account, message), checkBusy, notes, uniqueEntities, isPending, isPublic, isPublished.
But really, if you have to maintain JavaScript-less functionality for a web site (not a web app), that's a fine way to do it. Pull all of your data out of the data attributes once at load time, and you're off to the races.
considering that... backbone is not exactly what I need, but it is definitely inspiring for refining my own solutions (which again, are drawn from similar conclusions).
It's an interesting thought, though. However, I don't know if I'd see the need for something like backbone on any site where I was trying to support non-js browsers.
ps. thanks for reading my post simon, u da man!
I'm glad you liked my post.
Regarding "keeping models simple". Perhaps I wasn't so clear. My point here was mainly just that when I first started trying to build a model layer separate from the DOM (pre-backbone). I was very explicitly defining what attributes each model has and then also doing the corresponding DOM manipulations in my setters and getters. That got messy pretty quickly.
So, my point was not that you shouldn't add methods to your Backbone.Model's, but rather that you should keep view and controller logic out of your model layer.
Then I discovered sammy.js, which provides a nice approach to routing and linking. my current project uses that, and i roll my own data access code & use EJS for templating. I also have written all my own glue.
The space is calling out for a "Javascript on Rails" that takes a variety of different libraries and combines them in a canonical way so that each new project doesn't have to go through a shopping expedition, deciding which libraries are currently the best.
What's needed, basically:
1. Routing, navigation + back-button. Single-page JS apps operate very differently from normal apps because many links are hash links, eg. #settings. Sammy.js handles this nicely.
2. models. Here I have a different definition of what a model is than Backbone. I see a model as a class that wraps a particular service. So you might have a TwitterModel, YouTubeModel, MyServiceModel, etc. They would all benefit from inheriting from a base class that does the necessary networking (JSONP, JSON, etc.). It would be nice if all data came back from the service in the form of a Backbone.js Collection.
3. Views. There is a lot of code that ends up being needed around rendering templates. Think of the variety of different render() functions that exist in rails. That translates to Javascript, in my experience. Rendering templates into a div, doing pre- and post- processing, even swapping rendered blocks into invisible divs so they can be swapped back in quickly when the user hits the back button.
I could go on about the neat things that could/should be done, including all the declarative programming and "convention over configuration" stuff that rails does (example: render_foo() loads template foo.ejs and renders it into <div id='foo'>)
Anyway I feel myself a bit lost in a sea of googling whenever I try to find the definitive projects in this space - so I hope some will comment with their fave MVC-esque projects for Javascript...
I see what you're saying about "Javascript on Rails" but to me that's quite different than something like backbone. What you're talking about is more about "ajaxifying" a traditional browse-from-page-to-page experience. I definitely think there's value in that for improving the feel and responsiveness of a site. However, I'm more interested in truly emulating the desktop app experience where, once you log in there is no concept of browsing from page to page or "going back".
http://github.com/documentcloud/backbone/issues#issue/35
The big question is if it's useful enough -- Models/Collections/Views are used constantly, whereas hashchange routing is a comparatively tiny part of an app. For the record, the previous Backbone+Sammy discussion is here:
http://news.ycombinator.com/item?id=1788456
And there's another on the Sammy list:
http://groups.google.com/group/sammyjs/browse_thread/thread/...
Sounds like a better than the age-old hashtag workaround.
- Crockford originally thought it worthwhile to emulate classical inheritance
- so many, many other frameworks (and technique essays) provide various flavors of class-based inheritance
and that:
- even embracing true prototypical inheritance requires additional helper functions (or at least did in EcmaScript 3)
...I'm a little confused that you disagree that "there is no self-evident approach" for dealing with JavaScript's 'conflicted' (as the linked article correctly states) way of being a so-called prototypical language.
Crockford's prototypal revelation is only a slight alteration of the standard constructor pattern, and not a particularly useful one. You still have a class (the object that serves as a prototype for every instance you create), it doesn't add any particular flexibility, and it's quite slow. I encourage you to run the tests yourself:
http://jsperf.com/object-create-vs-crockford-vs-jorge-vs-con...
For me, that test clocks using Crockford's pattern to instantiate objects as 80% slower in Safari and Firefox, and 95% slower in Chrome, when compared to a standard use of JS prototypes.