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