2012-03-25 17 views
8

Estoy tratando de actualizar un componente principal de un evento de componente compuesto usando f:ajax.Componente compuesto de JSF <f:ajax> contiene un ID desconocido - no lo puede encontrar en el contexto del componente

El componente compuesto está aquí:

<cc:interface> 
    <cc:attribute name="update" /> 
    <cc:attribute name="customid" required="true"/> 
    <cc:attribute name="val" required="true"/> 
    <cc:attribute name="selectedvalue" required="true"/> 
</cc:interface> 
<cc:implementation> 
    <h:panelGrid columns="2" style="font-size: 10px" > 
     <p:selectOneMenu id="#{cc.attrs.customid} value="#{cc.attrs.selectedvalue}"> 
      <f:selectItems value="#{cc.attrs.val}"/> 
      <f:ajax event="change" render="#{cc.attrs.update" /> 
     </p:selectOneMenu> 
     <p:commandButton type="button" icon="ui-icon-plus" onclick="dlg.show();" /> 
    </h:panelGrid> 
</cc:implementation> 

Ahora, cuando el uso de este componente de la siguiente manera:

<h:form> 
    <ez:combo customid="make" val="#{vehicleBean.makes}" selectedvalue="#vehicleBean.vehicle.make}" update="model" /> 
    <p:selectOneMenu id="model" value="#{vehicleBean.vehicle.model}"> 
     <f:selectItems value="#{vehicleBean.models}" /> 
    </p:selectOneMenu> 
</h:form> 

me sale el siguiente error:

contiene un ID desconocido 'modelo' - no puede ubicarlo en el contexto del componente make

+0

no es mal (faltante}) – lu4242

Respuesta

15

Dado que el compone nt para actualizar está fuera del cc tiene que abordarlo de una manera diferente. En primer lugar dar a su forma un id:

<h:form id="myform"> 

luego insertar una dirección del componente de destino de su cc de esta manera:

render=":myform:model" 

Aviso colon de arrastre que permite JSF buscar el atributo de la raíz del documento.

+0

Todavía incapaz de encontrar .. contiene un ID desconocido ': myform: Modelo ' –

+1

Compruebe la fuente html generada en el navegador para obtener la ID correcta. Tal vez tenga otro NamingContainer en su árbol de documentos que no haya mostrado en su pregunta –

+0

Gracias. Matt funciona. –

4

Tuve el mismo problema hace un tiempo, solo para información, verifiqué las fuentes de la implementación de jsf mojara; aquí es cómo parece que funciona: La clase ajaxBehaviorRendered, cuando se encuentra con un f: ajax elemento de render, analiza el contenido de la rendir atribuir a través de su método de getResolvedId:


private static String getResolvedId(UIComponent component, String id) { 

     UIComponent resolvedComponent = component.findComponent(id); 
     if (resolvedComponent == null) { 
... 

El punto es el método findComponent: este necesita de la base del componente básico como punto de referencia para buscar en el árbol de componentes. Si el identificador comienza con el carácter ":", la base del componente es viewRoot.



    UIComponent base = this; 
    if (expr.charAt(0) == sepChar) { 
     // Absolute searches start at the root of the tree 
     while (base.getParent() != null) { 
      base = base.getParent(); 
     } 
     expr = expr.substring(1); 
    } 

lo contrario el componente base es el padre del componente de corriente más cercana del tipo NamingContainer (es decir, el componente compuesto en el que está definiendo su componente Ajax).



    //Treat remainder of the expression as relative 
    else if (!(base instanceof NamingContainer)) { 
     // Relative expressions start at the closest NamingContainer or root 
     while (base.getParent() != null) { 
      if (base instanceof NamingContainer) { 
       break; 
      } 
      base = base.getParent(); 
     } 
    } 

Luego, en ambos casos, comienza a buscar el componente con el identificador dado desde este comienzo.

Este comportamiento es el especificado de jsf.

Desde mi punto de vista, si necesita hacer referencia a un componente fuera del compuesto, debe definir el nombre completo, use el prefijo ':' seguido del atributo 'cc.clientId'.

+0

Punto muy interesante, gracias. Por cierto, ¿por qué no podemos simplemente especificar el atributo de representación como ': client_id' omitiendo el id del formulario padre? –

+0

No he trabajado con JSF desde hace 2 años, espero no responder algo tonto. Por lo que recuerdo (pero no estoy seguro), el ciclo de vida JSF, cuando procesa el árbol de componentes y encuentra un componente dentro de un formulario, prefija automáticamente el identificador de este componente con el identificador del formulario. Por lo tanto, no puede resolver el ": client_id" ya que su identificador real es "form_id: client_id". Pero debería ser revisado ya que perdí el foco en JSF durante los 2 años pasados. –

+0

Entonces, sí, el algoritmo componentSEarch necesita la ruta completa a un componente. ¿No sabes si es algo específico para la implementación de Mojarra? –

Cuestiones relacionadas