[jsr-314-open] Ajax rendering of components among compositions?
Jim Driscoll
Jim.Driscoll at SUN.COM
Tue May 26 16:12:36 EDT 2009
I read this and thought "darn it, I *remember* that discussion, now that
he brings it up". And then, apparently, completely forgot that we
added this functionality. My apologies.
The switchlist example predates the naming change, going back to the
dark days when we were just doing simple substitution into the JS function.
Other comments inline.
On 5/25/09 3:43 PM, Andy Schwartz wrote:
<snip>
>
> This will result in the search expression "form1:switchlist:list1" being
> resolved relative to the nearest naming container, which in this case is
> the switchlist composite component itself. Since there is no
> "form1:switchlist:list1" component within the composite component naming
> container, findComponent() would return null, and the <f:ajax> tag
> should log a warning.
Since that resolving code is only called by different function that
immediately fails if it doesn't find the id, a warning seems
unnecessary. An expanded error message was used instead.
> However, instead of failing/logging a warning, we've got some code in
> AjaxBehaviorRenderer.findComponent() that does the following:
>
>> UIComponent resolvedComponent = component.findComponent(expr);
>> if (resolvedComponent == null) {
>> // not found using a relative search, try an absolute search
>> resolvedComponent = component.findComponent(':' + expr);
>> }
>
> The bonus absolute search is not part of the spec - ie. is not typical
> findComponent() id resolution behavior. This code should be removed and
> replaced by a warning. (We should be able to make the warning clearer by
> identifying the naming container that provided the scope of the search.
Logged as bug 1134
Fix checked in.
> In any case, when switching over to:
>
>> <f:ajax execute="@this list1" render="list1 list2"/>
>
>
> Everything works as expected. We definitely should update this demo to
> use this simpler, more spec-compliant solution.
Done. Much cleaner.
> In order to try to reproduce the problem that David was seeing, I
> decided to see whether I could update the "reload" button on the main
> page from within the composite component. So, first I gave the reload
> button an id:
>
>> <h:commandButton value="reload" type="submit" id="reload"/>
>
>
> And then I added a new render target inside of our <f:ajax> tag (inside
> of the composite component):
>
>> <f:ajax execute="@this list1" render="list1 list2
>> :#{cc.parent.clientId}:reload"/>
>
>
> Note that I used the leading ":" character to indicate that this is an
> absolute id.
>
> I was thinking that "#{cc.parent}" would resolve to the composite
> component's immediate parent, which in this case happens to be the
> "form1" component. As such, I figured that "#{cc.parent.clientId}" would
> give me "form1", and ":#{cc.parent.clientId}:reload" would produce the
> absolute id ":form1:reload", which should target the outer reload button
> (leaving aside the question of whether this is a good thing to do or not).
>
> However, when I ran the test case, I hit the following error:
>
>> <f:ajax> contains an unknown id '::reload'
>
>
> Okay, that's weird. So this means that "#{cc.parent.clientId}" is not
> resolving to the parent component's client id, but instead to null/empty
> string. Huh.
>
> After poking around some more, I found my way to the
> com.sun.faces.el.CompositeComponentAttributesELResolver, which provides
> some special handling for certain properties on the "cc" object,
> including the "parent" property:
>
>> if (COMPOSITE_COMPONENT_PARENT_NAME.equals(propertyName)) {
>> UIComponent c = (UIComponent) base;
>> context.setPropertyResolved(true);
>> UIComponent ccParent = UIComponent.getCompositeComponentParent(c);
>> return ccParent;
>> }
>
>
> And, of course, UIComponent.getCompositeComponentParent() does not
> return the composite component's parent, but instead returns the nearest
> ancestor composite component. Which, in this particular demo, is...
> null. Yuck. Okay, in retrospect, rather than re-defining the meaning of
> "parent" here, we should have introduced a new derived property, eg.
> "compositeParent", or something along those lines. (Unfortunately the
> current behavior is defined by the spec - section 5.6.2.2, so too late
> to do anything about this for 2.0.)
After thinking over this for a while, a lack of a real "parent" object
may not be a bad thing.
After all, we'll want to tell people not to make components that
invisibly modify the using page. If you want to modify the using page,
you should have to explicitly make the user say so, and mark the id's to
be changed, or else you're going to make stuff that's impossible to
maintain.
<snip>
Jim
More information about the jsr-314-open-mirror
mailing list