Tuesday, September 04, 2012

knockout.composite: Getting Around

*UPDATE* Tribe is here! Check out http://tribejs.com/ for guides and API reference.

This is part 3 of a multi-part post. It’s assumed that you have a basic knowledge of the data binding and observability features of knockout.js.

Part 1: Introducing knockout.composite
Part 2: The Basics
Part 3: Getting Around
Part 4: Putting it All Together
Part 5: Unit Testing: Model Citizens 
Part 6: Integration Testing: Playing Nicely Together
Part 7: Functional Testing: Automated UI Tests, Anywhere, Any Time
Part 8: Pack Your App and Make it Fly
Part 9: Parting Thoughts and Future Directions


So we know how to show some stuff on the screen. Cool, but every app has different places we can go, precisely how are we going to get there? If you’ve used knockout a bit before, you might have already guessed we can feed the pane binding handler an observable, and this is most useful, but we’ve got another way that has some extra sugar coating.

Navigation (demo)

Along the way to being rendered in elegant beauty, a pane also takes on a life… err… object of it’s own. This object is passed to the constructor of each model and exposes all sorts of useful stuff. In this case, we’re interested in the navigate method.

The navigate method looks pretty much the same as the binding handler. Give it a path and data or an options object.

pane.navigate('end', { value: self.value() });

This does a few funky things.

Well… Navigates!

The pane that has been marked as the “navigation” pane (read: content pane) empties out it’s contents and loads up the new pane. By default, this is the root pane in your application, but we can control this by passing the handlesNavigation option to our panes. This allows us to easily declare some static layout that remains in place for the life of the application.

Memory Management

First, as mentioned, it cleans up any message subscriptions the current pane might have left lying around.

Single page web apps, along with all their slick, juicy, sweetness, bring the age old issue of memory leaks to the browser. As our pubsub objects tend to live for quite some time, we need to make sure they don’t hold references to subscription functions on our models for any longer than required.

This mechanism deals with most subscriptions, except for “persistent” subscriptions described in part 2. The next version of knockout.composite will have a vastly improved model where subscriptions (as well as global DOM event handlers) will be tied to the life of the pane’s corresponding DOM element.


Second, it triggers some automated visual prettiness. What’s a web framework without transitions? Currently, only basic hide / show and fade out / in transitions are implemented, but additional transitions can be implemented with ease. I’ll be implementing some of the basic CSS3 transitions and will post a guide on custom transitions soon.

Back Button and Bookmarking Support

Third, it populates our current URL hash tag with our pane path and data. Bookmarking and back button support for most applications without an extra line of code. Cool.

An observable extension that allows you to automatically persist the value of any observable in the URL is also provided.

self.selectedFolder = ko.observable().extend({ history: { key: 'folder', pane: pane } });

Passing the pane is optional but ensures the property is removed from the URL when the pane is destroyed.

Note: this extension is still being developed and there are a couple of known issues. They are minor, do not affect the API and will be fixed soon.

The Future…

It’s occurring to me as I write this that the sugar described above doesn’t necessarily need to be triggered by calling a function and can be integrated  and automated much more seamlessly. Future version.

As for this series of posts, in part 4 we’ll be putting all this into practice and building something functional.


Post a Comment

Note: Only a member of this blog may post a comment.

<< Home