Bug in the spec ;)
regards,
Martin
On Fri, Feb 22, 2008 at 6:35 PM, Matthias Wessendorf [EMAIL PROTECTED] wrote:
Hi,
it can be the case, that this mail may be a bit long..., but the main
question I think is:
Is there a public getPhaseListeners() method missing on UIVIewRoot ?
Some general information since JSF 1.2... there is a public
addPhaseListener() on UIViewRoot.
So you can register a PhaseListener with the current view root (per
view) to have beforePhase and afterPhase called
on these lifecycle phases:
-ApplyReqValue
-processValidation
-UpdateModel
-Invoke App
-RenderResponse
You can add such a PL (PhaseListener) via the mentioned Java API or:
f:phaseListener type=blah.MyPL /
(this internally uses the Java API )
Fine.
now when you render a page and do a (regular) postback the
phaselistener (its methods...) is executed.
Fine.
Now the ajax scenario.
Some libraries (like ADF Faces Rich Client or Apache MyFaces
Tobago(not Trinidad ;-) )) offer a custom lifecycle to call the
lifecycle methods (such as processXyz()) only
on the components, that are part of the ajax postback (why doing a
decode on not effected components?).
we do it like:
uiViewRoot.invokeOnComponent(context, clientId, callback);
where the *callback* is something like:
static private class UpdateModelValuesCallback implements ContextCallback
{
public void invokeContextCallback(FacesContext context,
UIComponent target)
{
target.processUpdates(context);
}
}
usually these *optimized* lifecycles offer optimization for these phases:
-ApplyReqValue
-processValidation
-UpdateModel
not on:
-Invoke App
-RenderResponse
For these, we just do a delegate back to the standard (default) behavior,
like:
viewRoot.processApplication(context);
So now the processXyz (like processUpdates()) is only! called on
the ajax components!
(Tobago does that in a similar way. They *fake* invokeOnComponent,
since that lib is JSF 1.1 based)
What does that mean, when submitting an ajax postback (maybe triggered
by inputText autoSubmit=true /) ?
The (to uiviewRoot) attached PL is only invoked for these phases:
-Invoke App
-RenderResponse
Why?
The big problem (IMO) is, that the PhaseListener(s) attached to the
current (per view) UIViewRoot are *triggered* by the processXyz() of
UIViewRoot itself (and encodeEnd and encodeBegin for RenderResponse phase).
So... when only invoking them on the effected ajax components the
before/afterPhase is never triggered (for the optimized phase).
The optimized lifecycle could get the attached PhaseListeners, in case
there where a public getPhaseListeners() method on UIViewRoot.
I am wondering why there is none ? Simply forgotten?
Please note, that (also since JSF 1.2) you can register methodExpression
like:
f:view beforePhase=#{methodExpression}
afterPhase=#{otherMethodExpression}
but... there is acutally a public getBeforePhaseListener() and a
getAfterPhaseListener() as well.
So a optimized lifecycle could get these MethodExpressions.
What is your take on that?
Thanks for reading,
Matthias
--
Matthias Wessendorf
further stuff:
blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
mail: matzew-at-apache-dot-org
--
http://www.irian.at
Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German
Professional Support for Apache MyFaces