* 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.
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.
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.
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:
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.
- Crockford originally thought it worthwhile to emulate classical inheritance
- so many, many other frameworks (and technique essays) provide various flavors of class-based inheritance
- even embracing true prototypical inheritance requires additional helper functions (or at least did in EcmaScript 3)
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.
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.
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'>)
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:
And there's another on the Sammy list:
Sounds like a better than the age-old hashtag workaround.