Tuesday, May 8, 2012

how to display a collection

There are two options when displaying a collection of controls, both with their drawbacks.

Refresh

The easiest one to master is the refresh. All you need to do is listen to any change to the collection then scrap all the child controls and re-render new ones. It's simple and means that your child controls won't need listeners on the models to change presentation - instead you can put logic in your templates to display the control with the model's current state.

This is the approach I've taken with the todomvc. It uses a lot less code (in fact compiled it is the smallest example on the entire site including the pure closure example - and it includes extra feats like routing!) and is pretty efficient for small lists. It can be slow though as it removes all the controls first and re-renders them and can cause memory leaks.

You should be cleaning up listeners on elements every time you remove a control. Luckily the closure library uses good.ui.component and automatically will cleanup listeners for you when you call dispose(). This wonderful mechanism has been used by mvc.Control so anytime you call a this.on, this.click, this.bind, etc. the handler is registered on the control and will be removed when you call mvc.Control#dispose().

Pretty neat eh? So PlastronJS has all the mechanisms you need to make this happen. It can cleanup for you on the refresh and can listen to any changes on a child that need you to refresh (anyModelChange).

Individual Updates

Now to the tricky part. What happens if you have complex child controls? well PlastronJS helps you with this as well. the collection has a listener for modelChange which only fires when the shape of the children change. Now what do I mean by shape?

The shape of the children refers to changes in sort order, or adding or removing children. If you want you can think of it as comparing an array of just the child model ids. So if you update a child but the list order doesn't change then modelChange will not fire. This means no re-rendering the entire list just for one small change.

But this comes at the price of complexity. The child models now have to manage their own display with listeners on their models. You will also need to write a function to run through the controls children and match the existing controls with it's collections child models, but what it means is less changes to the DOM and a faster site.

The truth is it can be complex managing this - (what happens if the child control disposes itself? how should you shuffle around the resorted nodes?) and as yet PlastronJS leaves you with the details.

In the next iteration though I'm planning some way of letting you attach what a child control should look like and have PlastronJS deal with the shape changes by moving controls in the least amount of steps. This will probably come as a new mvc.ListControl that inherits from mvc.Control so stay tuned!

No comments:

Post a Comment