jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [jsr372-experts mirror] Re: Improve vdl.createComponent(...) to use ui:include and user tags

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Thu, 30 Oct 2014 00:25:23 -0500

Hi

2014-10-29 14:56 GMT-05:00 arjan tijms <arjan.tijms_at_gmail.com>:
> Hi,
>
> On Wed, Oct 29, 2014 at 6:39 PM, Leonardo Uribe <leonardo.uribe_at_irian.at> wrote:
>> just create one facelet and then attach that facelet in the component tree.
>>
>> [...]
>>
>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-611
>> Export FaceletFactory as a standard artifact vended from FactoryFinder.
>> [...]
>> It was mentioned that add FaceletFactory "as is" was too inconvenient.
>
> Before diving into the main issue you addressed, just wanted to
> quickly comment on this one.
>
> The standard FaceletFactory would not only have been convenient to
> programmatically create a Facelet, but also to get a hold of the
> component tree before it's being state tracked and everything. This
> could then allow one to programmatically add components without the
> runtime knowing or caring that they were dynamically added. I.e. it
> would be just like one "dynamically" creates components from within a
> Facelet using c:if and friends.
>

As far as I can remember, the hack done in MyFaces support c:if tag.

> At the moment none of the existing abstractions in JSF seem to be able
> to offer this conveniently. ViewDeclarationLanguage#buildView comes
> close, but does a little too much.
>

An example of how to write that abstraction could help, to see how far
can we go with the idea.

>> If you guys think this is a good idea, please say something, so we can put
>> more weight in and get it done.
>
> I think it's a good idea by itself really. It also ties in with the
> themes of emphasizing and strengthening JSF's strong point of being
> able to do dynamic component tree manipulation (if I'm not mistaken,
> not all component based web frameworks can do this), and the theme of
> sorts to let the user work with the Java API from the point of view of
> tag library URIs and tag names.
>

To provide fully dynamic component tree manipulation we still need some
more hacks to do.

One of them is what happen when you do some manipulation through ajax
and you need to load one css or js, because you have loaded a new
component. Right now, JSF doesn't detect that, but in MyFaces we have a
param called

org.apache.myfaces.STRICT_JSF_2_REFRESH_TARGET_AJAX

if it detects a change in the resources, it forces update <head> tag, adding
the necessary .js or .css file. But it is not perfect, because the idea is
something that just add the file inside <head> tag, not force refresh the
whole tag. The problem is it require some changes in PartialViewContext,
but some third party libraries overrides that part.

See:

https://issues.apache.org/jira/browse/MYFACES-3106

For details and the discussion with the user:

"... So the only workaround would be to add every possible richfaces and
primefaces component to the login page so it loads the JS and css. That's
 a bit depressing because you can't create a "pure ajax"/dynamic
application in JSF2 even tho i was possible in JSF1. ...".

Please note there is another issue with ajax. Sometimes you want to add
a render or execute target dynamically. For example, a component wants
to show a message, so you need that the current ajax request include
an update to that message box. PartialViewContext doesn't provide a
solution "out of the box", so you are forced to write that logic. This is
related to the one we are discussing, because this is just a variant of
the more general problem.

> One thing I was thinking about though is whether it would make sense
> to have an additional method returning a List<UIComponent> for those
> cases that the user indeed wants to have all the components in the
> Facelets include or Facelets tag and doesn't want the wrapper. Or,
> would the user be expected to simply take the components from the
> children collection of the wrapper component and then discard the
> wrapper? I would be okay with either solution I think but just wanted
> to throw the idea out there.
>

I think the UIComponent wrapper is very convenient because it is necessary
to add some special code inside the wrapper to make it work. For example
when you need to refresh from a facelet, you know all components involved
are inside the wrapper. I haven't found an use case that requires the
List<UIComponent>. The reason is the only thing you really need is to call
facelets. Then, since facelets is in control, you can do whatever you want
there.

regards,

Leonardo Uribe

> Kind regards,
> Arjan Tijms