This is a sandbox page for a suggestion for some changes of the ResponseBuilder API, By Ron Piterman
Currently, I am working on an application which makes a very extensive use of Ajax based on tapestry 4.0.
We started prototyping a few monthes ago and are moving into implementation just as 4.1 is released - and are considering moving to 4.1, but found that the current API is insufficient to cover some important use cases we deal with.
While giving answer to several Ajax Rendering use cases, the current API apears to be not flexible enough and non extendable:
Current Response rendering and processing
<xxx type="TYPE" id="ID">...</xxx>
Where TYPE is either "exception" , "script" or ignored and ID is either a script role ("initializationscript" , "bodyscript" , "includescript" ) or an ID of an html element in the document to replace.
The ResponseBuilder interface contains methods to support exactly these types and IDs - and some other which are used for example in the JSON response builder.
what this does not cover
The current use-cases we have, and which are not covered by this API are in general passing XML/HTML rendered by tapestry as parameters to function calls on dojo widgets.
Our application makes intensive use of tables. Many of these tables have hierarchical structure of :
- header-row (selected )
The table is rendered by a custom component backed by a custom model, which is designed to render on demand only specific rows, according to the request - this is an application design decision, beacuase rendering the whole table is very expensive for the database and the backend.
When the user clicks one of the not-selected header-rows, only the needed child rows are rendered, and tapestry sends an RPC to the to-be selected row-widget, passing the rendered rows as parameters, which are then added to the document into the right position.
The rows of the group which was previously selected are discarded from the document.
My suggestion would be:
instead of the different write methods (writeBodyScript , writeInitializationScript, writeInitializationScript , writeExternalScript ) and the corresponding isXXXAllowed, use one single method:
write( String type, String script, IReqeustCycle cycle );
write( String type, IRender render, IRequestCycle );
updateComponent( String type , String ...ids );
create a hivemind configuration for the response builder and let different services handle the string/Irender and render any desired xml around them.
The services would need also some kind of event-calls to allow them to respond to response rendering cycle events.
Now the change described above is a major API change, but it does allow an easy refactoring with deprecation.
Alternativley, it would be enough for my company's case, if a method updateComponent( id , callbackName ) is added, which renders an <xxx type="callback" id="..." callback="callbackName"> -
The tapestry.load method could then call callbackName on the widget which is the source of the event which triggered the Ajax-request.