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]

Reply via email to