One of the major changes taking place in the 5.4 branch is the choice between explicit initialization and unobtrusive initialization.
Tapestry has traditionally used explicit initialization: - render and element, with a specific id - generate "parameters" object that describes the behavior, and references that id - import a JavaScript library that provides a T5.initializers function - Invoke that function with the parameters object when the page loads With 5.4, we're leveraging unobtrusive initialization. In this style, specific elements have special class names (or, increasingly, data- attributes). A module is imported that provides a document-level event handler for events (both DOM events, and custom events) that originate in such elements. Sometimes groups of data-attributes work together, for example in 5.4, validation now looks something like this: <input ... data-validate="true" data-optionality="required" data-required-message="You most provide a user name."/> What's nice about this approach is that, when new content is added to the page via Ajax or DHTML, the underlying validation behavior is instantly in place ... no wait of any kind for initialization, and no processing time spent performing the initialization. Likewise, if content is removed from the DOM, there's no possibility (even in IE) of memory leaks from cycles between JavaScript objects and closures, and DOM objects. A nice note about this is that even elements that are rendered entirely on the client (perhaps using Backbone, as with my main client projects) can now pretty easily participate in validation, just by providing the right data- attributes. At some point, we'll need to create a dictionary of these different attributes and how they related to each other! This unobtrusive, attribute-driven, approach works great on things that are rendered entirely the server side. As I'm recoding more sophisticated components, such as the Palette, I'm hitting components that want to do some rendering or setup on the client. Even here, there's room for explicit or unobtrusive. To accomplish unobtrusive, we could do a scan when the page loads for elements; for instance, the Palette component could render a data-component-type="core/Palette" attribute, and code inside the core/palette module could locate such elements and wire them up. The challenge there is that, on an Ajax update, we need to scan the newly added content and the DOM does not directly provide a way to do that. However, the Zone component (and other things that act like a Zone) emit custom events before and after updating the DOM. So we could do one scan on initial page load, and an additional scan, just on updated zone content, whenever a zone does in fact update. The advantage here is moving away from Tapestry-generated unique ids, and all the confusion associated with them. Has anyone else pursued the unobstrusive/scanning approach (outside of Tapestry)? Currently, the work I'm doing on Palette leaves it in the explicit initialization camp. The trade-off for me is the expense of lots of document scans looking for elements to initialize; I'm sure a larger app with many big custom components could end up spending a lot of cycles doing just that after every dynamic update. However, the appeal of going "id free" is compelling. -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com