[jsr-314-open-mirror] [jsr-314-open] composite components: targets attribute revisited

Ganesh ganesh at j4fry.org
Thu Oct 28 15:44:02 EDT 2010


Leo, IMO your example wouldn't need to fail: the nested actionListener with binding="#{cc.actionSource.loginEvent}" would need to execute *all* actionListeners that have been bound to "loginEvent". In this case "#{bean.loginEventListener}" and "#{bean.loginEventListener2}" would reside in a Map named cc.actionSource.loginEvent and could both be executed. Wouldn't this work?

IMO Jakob's approach #2 would work, is easy to understand and logical within the entire context. I think acceptance will be better than targets, methodTarget or methodType constructs, because this is what I tried first before realizing how this entire thing was set up and I saw other developers getting into JSF 2 and running exactly the way #2 Jakob proposed.

Best regards,
Ganesh

Am 28.10.2010 19:56, schrieb Leonardo Uribe:
> Hi
>
> To be more explicit, this is the example that should fail:
>
> <ez:loginPanel id="loginPanel" model="#{bean}">
> <f:actionListener for="loginEvent"
>                           binding="#{bean.loginEventListener}" />
> <f:actionListener for="loginEvent"
>                           binding="#{bean.loginEventListener2}" />
> <f:actionListener for="cancelEvent"
>                           binding="#{bean.cancelEventListener}" />
> </ez:loginPanel>
>
> <composite:interface name="loginPanel">
> <composite:actionSource name="loginEvent" />
> <composite:actionSource name="cancelEvent" />
> </composite:interface>
> <composite:implementation>
> <h:commandButton name="button1">
> <f:actionListener
> binding="#{cc.actionSource.loginEvent}"/>
> </h:commandButton>
> <x:mycompositecomponent name="button2">
> <f:actionListener
> binding="#{cc.actionSource.cancelEvent}" for="someOtherEvent"/>
> </x:mycompositecomponent>
> </composite:implementation>
>
> In this case, the binding #{cc.actionSource.loginEvent} does not point to just
> one actionListener.
>
> regards,
>
> Leonardo
>
>
> 2010/10/28 Jakob Korherr <jakob.korherr at gmail.com <mailto:jakob.korherr at gmail.com>>
>
>     Hi,
>
>     In option 2 the f:actionListener is just used as a reference to the
>     cc:actionSource (just as in option 1 but without introducing a new
>     composite-tag).
>
>     Thus it would actually be possible to have multiple ones!
>
>     Regards,
>     Jakob
>
>     2010/10/28 Leonardo Uribe <lu4242 at gmail.com <mailto:lu4242 at gmail.com>>:
>      > Hi
>      >
>      > 2010/10/28 Jakob Korherr <jakob.korherr at gmail.com <mailto:jakob.korherr at gmail.com>>
>      >>
>      >> Hi,
>      >>
>      >> Currently there are a lot of discussions (on spec-issues, on this list
>      >> and also internally) about the problems with the targets attribute in
>      >> the composite component interface and I'd like to wrap these up here.
>      >>
>      >> IMHO the targets attribute is something we should get rid of, because
>      >> it directly points to the implementation section and frankly somehow
>      >> feels like the following piece of code:
>      >>
>      >> if (this instanceof Foo)
>      >> {
>      >>    // do something
>      >> }
>      >>
>      >> The interface section should just specify the interface for the
>      >> composite component and should not include any information about the
>      >> implementation section. However, the implementation section should of
>      >> course refer to the interface section. Unfortunately the targets
>      >> attribute works against this. And furthermore the targets attribute
>      >> also confuses users, because the don't really know which clientid to
>      >> use (especially with nested components in the implementation section).
>      >>
>      >> The first step needed here is to put all attributes (also the
>      >> "well-known" ones like action, actionListener, valueChangeListener) on
>      >> the composite component attribute map in order to access them via
>      >> #{cc.attrs.attributeName}. In this way the user can refer from the
>      >> implementation section to the related attribute in the interface
>      >> section, regardless of what it does. This was already discussed and is
>      >> also already accepted, I guess.
>      >>
>      >> The next step is to remove the targets attribute from cc:actionSource,
>      >> cc:editableValueHolder and cc:valueHolder. Here we have two options:
>      >>
>      >> 1) add new composite tags that insert the related listeners in the
>      >> implementation section (proposed by Leonardo):
>      >>
>      >> <ez:loginPanel id="loginPanel" model="#{bean}">
>      >> <f:actionListener for="loginEvent"
>      >>                          binding="#{bean.loginEventListener}" />
>      >> <f:actionListener for="cancelEvent"
>      >>                          binding="#{bean.cancelEventListener}" />
>      >> </ez:loginPanel>
>      >>
>      >> <composite:interface name="loginPanel">
>      >> <composite:actionSource name="loginEvent" />
>      >> <composite:actionSource name="cancelEvent" />
>      >> </composite:interface>
>      >> <composite:implementation>
>      >> <h:commandButton name="button1">
>      >> <composite:insertActionSource name="loginEvent"/>
>      >> </h:commandButton>
>      >> <x:mycompositecomponent name="button2">
>      >> <composite:insertActionSource
>      >> name="cancelEvent" for="someOtherEvent"/>
>      >> </x:mycompositecomponent>
>      >> </composite:implementation>
>      >>
>      >>
>      >> 2) use the existing tags like f:actionListener and
>      >> f:valueChangeListener and provide the actionSource,.. via
>      >> ValueExpression:
>      >>
>      >> <ez:loginPanel id="loginPanel" model="#{bean}">
>      >> <f:actionListener for="loginEvent"
>      >>                          binding="#{bean.loginEventListener}" />
>      >> <f:actionListener for="cancelEvent"
>      >>                          binding="#{bean.cancelEventListener}" />
>      >> </ez:loginPanel>
>      >>
>      >> <composite:interface name="loginPanel">
>      >> <composite:actionSource name="loginEvent" />
>      >> <composite:actionSource name="cancelEvent" />
>      >> </composite:interface>
>      >> <composite:implementation>
>      >> <h:commandButton name="button1">
>      >> <f:actionListener
>      >> binding="#{cc.actionSource.loginEvent}"/>
>      >> </h:commandButton>
>      >> <x:mycompositecomponent name="button2">
>      >> <f:actionListener
>      >> binding="#{cc.actionSource.cancelEvent}" for="someOtherEvent"/>
>      >> </x:mycompositecomponent>
>      >> </composite:implementation>
>      >>
>      >>
>      >> Frankly I'd prefer option 2, because it is very similar to how we
>      >> handle cc:attribute --> #{cc.attrs.xxx}.
>      >>
>      >>
>      >> One remaining problem here, however, is how to handle non-required
>      >> method-attributes (there's a thread about this on the
>      >> myfaces-user-list). IMO the default attribute of cc:attribute should
>      >> be able to resolve to a MethodExpression and not only to a String (I
>      >> think this is already a spec-issue), but it should also work without
>      >> providing a default value. In that case #{cc.attrs.thatAttribute}
>      >> should internally return an empty action/listener/... so that there
>      >> are no problems with the related implementation-components which refer
>      >> to this attribute.
>      >>
>      >> What do you think?
>      >>
>      >
>      > Well, unfortunately use option 2 forces to use just one f:actionListener per
>      > actionSource, and in theory, it should be possible to have multiple ones.
>      >
>      > best regards,
>      >
>      > Leonardo Uribe
>      >
>      >>
>      >> Regards,
>      >> Jakob
>      >>
>      >> --
>      >> Jakob Korherr
>      >>
>      >> blog: http://www.jakobk.com
>      >> twitter: http://twitter.com/jakobkorherr
>      >> work: http://www.irian.at
>      >
>      >
>
>
>
>     --
>     Jakob Korherr
>
>     blog: http://www.jakobk.com
>     twitter: http://twitter.com/jakobkorherr
>     work: http://www.irian.at
>
>

-- 
"There are two kinds of people in the world, those who believe there are two kinds of people and those who don't."
— Robert Benchley



More information about the jsr-314-open-mirror mailing list