Hi Sharath, it`s good that you are thinking of some improvements to the myfaces ajax api, I also wanted to do some changes to it, but didn`t had time anyway.
The issue that the code inside AjaxDecodePhaseListener is kind of disordered, lays in the fact that we were experimenting with our ajax components and in order to achieve a quick result everyone has put his corresponding component code inside it. I did this ugly stuff with if ..(component instanceof SuggestAjax).. in order to get a quickfix for the problem you mentioned (only xml like responses will work; special <response> treatment). TableSuggestAjax only works with plain text/html, therefore i needed this. So, i completely agree to reorganizing the code. To my mind,the only ajax components which we have alter to dojo are the inputAjax ones. Problem is, I think there is no directly counterpart (like a widget) to rely on, so there is the need to use dojo`s ajax api and other dojo packages. Seems to be much work for all the inputAjax components; we should first concentrate on reordering the api and migrate this step by step. What we will need anyway is the UIComponentPerspective stuff, otherwise we can not be sure to find components which are located inside dataTables. No further processing could be done. I think it can not be moved out of the phase listener. If we rely on our "affectedAjaxComponent" approach (seeking comp and calling methods on it) we are little bit restricted in coding. The only real thing we can do, is calling encodeAjax() and decodeAjax() from the phase listener (like it is now) and moving special handling to the component. Other special response treatments - like defining a different response format - could be done in the renderer. Maybe we can introduce a special wrapper which is aware of handling the ajax response format and which is treating it like we want to have it. Or shall we think of a completely new treatment of ajax components? cheers, Gerald On 4/29/06, sharath reddy <[EMAIL PROTECTED]> wrote:
Hello, Martin and I discussed the existing state of the AJAX functionality in MyFaces. We came up with some suggestions for improvement. Below is a brief discussion of how AJAX requests are handled in MyFaces, which may be useful to some, followed by our comments. Every component that has Ajax functionality is expected to implement the following interface: public interface AjaxComponent { void encodeAjax(FacesContext context) throws IOException; void decodeAjax(FacesContext context); } As can be expected, 'decodeAjax' is reponsible for parsing the request and updating the component, and 'encodeAjax' generates the response to the browser. A specialised phase-listener is registered on the 'Apply Request Values' phase. The functionality of this class is implemented in the 'beforePhase' method. The phase listener searches the input parameters for a parameter called 'affectedAjaxComponent'. If found, then the value of this parameter is the component id of the component that generated the AJAX request. If this parameter is not found, the phase listener exits. The phase listener finds the component and calls the methods 'encodeAjax and decodeAjax. If the parameter 'updateOnly' is found, then only encodeAjax is called. (This is incorrect. As mentioned previously, updates to the component are done in the 'decodeAjax' method. I think this should be renamed to 'encodeOnly'). If 'decodeAjax' is called, then the Phase Listener also calls the method 'facesContext.getViewRoot().processApplication(facesContext)', which executes any actions or actionListeners that may have been registered in the method 'decodeAjax'. String updateOnly = (String) facesContext.getExternalContext().getRequestParameterMap().get("updateOnly"); if(updateOnly == null) { // then decode decodeAjax(ajaxComponent, facesContext); facesContext.getViewRoot().processApplication(facesContext); } encodeAjax(ajaxComponent, facesContext); If server-side state-saving is configured, then the state of the view is saved. context.responseComplete is called. Here are some of the inputs we came up with: 1. There are too many special cases in the Phase Listener code: if (component instanceof SuggestAjax) //do something if (component instanceof HtmlCommandButtonAjax) .... if (ajaxComponent instanceof UIComponentPerspective) ... In our opinion, all this logic should be moved into their respective components. The phase listener should not be aware of these distinctions. 2. The responsibility for rendering the response should lie entirely with the component. The current code does something like this: out.print("<?xml version=\"1.0\"?>\n"); out.print("<response>\n"); ((AjaxComponent) component).encodeAjax(context); out.print("</response>"); Due to this approach, the component-writer has 2 disadvantages: a. He is forced to render an xml response. Other options are ruled out. b. If he wants to use an XML API (say, JDOM) to render the response, he is contrained, as the root element 'response' has already been rendered in the output stream. 3. The existing component(s) ? that still use Prototype library should be converted to use Dojo. Obviously the existing components will have to be altered concurrently with the changes in the Phase Listener, so that they continue working. Anyone have a suggestion for the best way to go forward? Regards, Sharath __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
-- Gerald Müllan Schelleingasse 2/11 1040 Vienna, Austria 0043 699 11772506 [EMAIL PROTECTED]