InfoQ Homepage Presentations Building Rich User Experiences without JavaScript Spaghetti
Building Rich User Experiences without JavaScript Spaghetti
Summary
Jared Faris provides 3 principles –decouple everything, make it testable, push events not state – and some patterns which help avoiding creating JavaScript spaghetti code over time.
Bio
Jared is a developer at Facio, a startup building tools to visualize how people work together to improve their happiness and productivity. He spends his time learning about new technologies and teaching them to others. As part of his desire to teach he helped cofound the CloudDevelop conference. You can find out more about him at http://jaredthenerd.com or follow him @jaredthenerd.
About the conference
Code PaLOUsa is a two-day software development conference to be held March 16 and 17, 2012 at the Marriott Louisville in downtown Louisville, KY. The conference is designed to cover all aspects of software development regardless of technology stack. We will have sessions revolving around Microsoft, Java, and other development platforms; along with the sessions on higher level topics that are platform agnostic. The conference schedule will feature presentations from well-known professionals in the software development community. There will be fifty-five hour-long presentations and panel discussions, plus a keynote each morning of the event.
Community comments
UI-level model instead?
by Rick Mugridge,
Re: UI-level model instead?
by Russell Leggett,
Re: UI-level model instead?
by Jared Faris,
UI-level model instead?
by Rick Mugridge,
Your message is awaiting moderation. Thank you for participating in the discussion.
Hi Jared,
I agree that code can easily become tangled, because the wiring is done too close to the (upper-most) GUI layer. So it feels like lots of hacks with no coherence. I know of at least two approaches, busses and GUI-level models.
It seems to me that your service bus works here because it's quite constrained in what it handles. I've seen such busses grow out of control as more is added, because they turn into a complex global with large numbers of dependencies. The complexity is in all the routing through the bus. And there will be lots of unrelated "interactions" going on, all blended together.
I approach this issue by having an explicit model for the state of selection/showing of the GUI, and this mediates the interactions between the GUI pieces. It has anonymous (multi-) listeners registered to respond to changes of interest to them. I can then TDD that model. It's flexible for plugging in additional capability. This allows me to create a coherent model with a clear focus.
I usually find that different people choose different solutions because of subtle differences in their goals. So I'd be interested to hear what aspects of your app meant that a bus is a better choice than a GUI-model approach.
Cheers, Rick
Re: UI-level model instead?
by Russell Leggett,
Your message is awaiting moderation. Thank you for participating in the discussion.
I'm pretty much with you Rick, especially if you have a rich data-binding layer. In the application I work on (client side templates and ~100,000 lines of JS code, dozens of screens, hundreds of rest services) it's rare that I ever have a situation which would benefit from a global bus approach. I've thought about it, and there are a few instances that might benefit, but I have found it overwhelmingly useful to have a model/binding centric approach with a judicious sprinkling of custom events. Your example of two controls interacting can easily be solved by having them share a data model describing the state of the app. Modification to state is observed through data bindings and automatically updated.
One of the core reasons why I find the model based approach to be advantageous is that it can be saved and reloaded in the same state, not to mention, if you are rendering everything in the client, you really need to have a model for it anyway, just so that you can supply the data for the template. With a little work, and a flexible UI framework, you can share a model with multiple views for example. One rendering makes the table, while another would render the selectable sidebar.
- Russ
Re: UI-level model instead?
by Jared Faris,
Your message is awaiting moderation. Thank you for participating in the discussion.
Hi Rick and Russ,
It depends on what I'm building. At the time I put together this talk I was building single pages of a more traditional multi-page app. A single bus worked out pretty well on the pages because for a) there wasn't a lot of unrelated messaging to complicate things and b) most of the elements on the page really cared about some identifier and then a few bits of information only they used. A message that identified the item could trigger a fresh pull of data from the server for what the control was interested in. Fresh data for a different related control wasn't always necessary. I've been able to build pretty nice applications really quickly this way.
On more complex things (like huge SPAs) I'm more likely to do something similar to what you're describing. When I've used Backbone.js I've created models for everything inside of a router and then reused those models in views when appropriate. I still end up passing a few events to an event aggregator but there aren't a huge number of them and it doesn't get messy.
One other benefits of the pattern I'm talking about is that it seems to click quickly for people who have done things like WPF or used the MVP pattern elsewhere. I've talked to a number of people who struggle with building organized JavaScript in general and have trouble wrapping their heads around shared model approaches. Having them start by building a single model for a single part of a page and then using messaging to connect things gets them moving towards elegant JS pretty quickly.
I may have totally missed parts of your feedback so if so please let me know. I don't necessarily disagree with either of you :)
-Jared