سؤال

I made a composite component, inside it is an <f:ajax> tag, and its "render" attribute is a parameter of the cc.

something like this:

    ...
    <cc:attribute name="additionalAjaxRenderIds" type="java.lang.String"></cc:attribute>
    ...
    <h:commandLink value="test" action="#{myBean.someAction}" id="testLink" >
        <f:ajax execute="@this" render="#{cc.attrs.additionalAjaxRenderIds} "/>
    </h:commandLink>
    ...

I use this cc inside a form, thats already in an outer naming container:

    <h:form id="myForm">
        ...
        <mycomp:myComponent id="myCC" additionalAjaxRenderIds=":#{component.namingContainer.parent.clientId}:myPanel" />
        <h:panelGroup id="myPanel">
            ...
        </h:panelGroup>
        ...
    </h:form>

The problem is, if i write

additionalAjaxRenderIds=":#{component.namingContainer.clientId}:myPanel"

i get this error:

<f:ajax> contains an unknown id ':j_idt44:myForm:myCC:myPanel' - cannot locate it in the context of the component testLink

while if i use this (+ .parent):

additionalAjaxRenderIds=":#{component.namingContainer.parent.clientId}:myPanel"

the error is:

<f:ajax> contains an unknown id ':j_idt44:myPanel' - cannot locate it in the context of the component testLink

instead of the expected id:

':j_idt44:myForm:myPanel'

so it seems like the parent of my cc's naming container is not the form, but the outer namingcontainer

Is there any way to: 1, get the right parent (the form) 2, evaluate the EL before i pass it as a parameter (so i can pass the calculated clientId to my cc instead of the EL expression, so the component wont refer to the commandLink tag, but to the h:form in which i put my cc)

I know i could use

additionalAjaxRenderIds=":#{component.namingContainer.parent.clientId}:myForm:myPanel" 

but i dont like that solution

Also, setting the form's prependId attribute to false breaks the whole component lookup (and the ajax tag too as a result)

هل كانت مفيدة؟

المحلول

EL expressions are not evaluated at the moment the component is built, but at the moment the attribute is accessed. In other words, they're runtime and not buildtime. The #{component} refers to the current UI component at the moment the EL expression is evaluated, which is in your particular case the <h:commandLink>. That explains the different outcome.

You need to approach this differently, without using #{component}.

E.g.

<h:form id="myForm" binding="#{myForm}">
    ...
    <mycomp:myComponent id="myCC" additionalAjaxRenderIds=":#{myForm.clientId}:myPanel" />
    <h:panelGroup id="myPanel">
        ...
    </h:panelGroup>
    ...
</h:form>

or

<h:form id="myForm">
    ...
    <mycomp:myComponent id="myCC" additionalAjaxRenderIds=":#{myPanel.clientId}" />
    <h:panelGroup id="myPanel" binding="#{myPanel}">
        ...
    </h:panelGroup>
    ...
</h:form>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top