ajax jsf-2 composite-component

Rendinging componente compuesto por ajax



jsf-2 composite-component (1)

Tengo un componente de construcción que se parece a esto:

<composite:interface> <composite:attribute name="id" required="false" /> <composite:attribute name="label" required="true" /> </composite:interface> <composite:implementation> <h:panelGroup id="#{cc.attrs.id}"> <fieldset class="fieldset"><legend>${cc.attrs.label}</legend></fieldset> </h:panelGroup> </composite:implementation>

El competidor muestra la etiqueta actual correctamente.

<xyz:comp id="idMyComponent" label="#{someBean.text}"/> ... <a4j:ajax ... render="idMyComponent" /> ...

Ahora cuando se realiza la acción, no pasa nada. Sin embargo, cuando agrego un Postfix a la ID en el componente, funciona bien (ver a continuación).

... <composite:implementation> <h:panelGroup id="#{cc.attrs.id}Label"> ...

Y defina la ID en el procesamiento con el postfijo:

<xyz:comp id="idMyComponent" label="#{someBean.text}"/> ... <a4j:ajax ... render="idMyComponentLabel" /> ...

¿Puede alguien explicarme por qué solo funciona cuando agrego un postfijo a la ID en h:panelGroup ?


Este problema es en realidad doble.

El primer problema es que el <xyz:comp id> realidad especifica el ID del componente compuesto en sí mismo , el <cc:implementation> . Por defecto, esto no está representado en ninguna salida HTML y, por lo tanto, ajax / JavaScript no puede ubicarlo en document.getElementById() y sus amigos.

En realidad, su <h:panelGroup id="#{cc.attrs.id}"> termina en el resultado HTML generado de la siguiente manera (haga clic con el botón derecho en la página y vea el código fuente para verlo usted mismo):

<span id="idMyComponent:idMyComponent">

El segundo "problema" es que RichFaces / Ajax4jsf ha mejorado la referencia / búsqueda de componentes JSF en el árbol por ID de cliente relativo (es decir, no comienza con NamingContainer buscando no solo en el contexto del NamingContainer actual, sino también en todos los demás Componentes de NamingContainer . Un componente compuesto es inherentemente también un componente NamingContainer .

Su primer intento falló porque encontró el compuesto en sí en lugar del grupo de paneles, pero JS / ajax a su vez no pudo actualizar porque no existe ningún elemento HTML con id="myComponent" en la salida HTML generada.

Su segundo intento tuvo éxito porque finalmente encontró el grupo de paneles real (nota: porque también buscó en todos los otros componentes de NamingContainer , esto aún habría fallado si ha utilizado <f:ajax> lugar de <a4j:ajax> ).

La forma correcta de solucionar su problema es no usar #{cc.attrs.id} en un componente JSF, pero usando #{cc.clientId} en un elemento HTML simple.

<span id="#{cc.clientId}">

(Sí, utilice un <span> o <div> lugar de <h:panelGroup> dentro de <cc:implementation> )

De esta forma, JSF puede encontrar el componente por ID de cliente (para generar la respuesta ajax adecuada) y JS puede encontrar el elemento HTML por ID de cliente (para actualizar el elemento HTML correcto en función de la respuesta ajax).

Ver también: