2012-03-25 16 views
8

Sto tentando di aggiornare un componente padre da un evento di componente composito utilizzando f:ajax.JSF Componente composito <f:ajax> contiene un ID sconosciuto - impossibile localizzarlo nel contesto del componente

Il componente composito è qui:

<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> 

Ora, quando si utilizza questo componente come segue:

<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> 

ottengo il seguente errore:

contiene un ID sconosciuto 'modello' - Impossibile localizzarlo nel contesto del componente make

+0

non è errato (mancante}) – lu4242

risposta

15

Dal momento che il componente nt per aggiornare è fuori dal cc devi affrontarlo in un modo diverso. In primo luogo dare il vostro modulo di un ID:

<h:form id="myform"> 

Poi affrontare la componente bersaglio dal tuo cc in questo modo:

render=":myform:model" 

Avviso colon finale che lascia JSF cercare l'attributo dalla radice del documento.

+0

Ancora impossibile trovare .. contiene un ID sconosciuto ': myform: modello ' –

+1

Controlla la sorgente html generata nel browser per l'id corretto. Forse hai un altro NamingContainer nell'albero del documento che non hai mostrato nella tua domanda –

+0

Grazie Matt funziona. –

4

Ho avuto lo stesso problema qualche tempo fa, solo per informazioni, ho controllato i sorgenti dell'implementazione di jsf mojara; ecco come sembra funzionare: La classe ajaxBehaviorRendered, quando incontra un f: ajax elemento di rendering, analizza il contenuto del rendering attribuire tramite le modalità getResolvedId:


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

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

Il punto è la metodo findComponent: questo ha bisogno della base del componente di base come punto di riferimento per la ricerca nell'albero dei componenti. Se l'identificatore inizia con il carattere ":", la base del componente è 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); 
    } 

Else componente di base è più vicino il genitore del componente corrente di tipo NamingContainer (vale a dire, il componente composito in cui si sta definendo il 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(); 
     } 
    } 

Poi, in entrambi i casi, si comincia a cercare il componente con l'identificatore data da questo inizio.

Questo comportamento è quello specificato da jsf.

Dal mio punto di vista, se è necessario fare riferimento a un componente esterno al composito, è necessario definire il nome completo, utilizzando il prefisso ':' seguito dall'attributo 'cc.clientId'.

+0

Punto molto interessante, grazie. A proposito, perché non possiamo semplicemente specificare l'attributo render come ': client_id? Ommiting l'id del form principale? –

+0

Non lavoro con JSF da 2 anni, spero di non rispondere a qualcosa di stupido. Da quello che ricordo (ma non ne sono proprio sicuro), il ciclo di vita JSF, quando elabora l'albero dei componenti e trova un componente all'interno di un modulo, prefisso automaticamente l'identificatore di questo componente con l'identificatore del modulo. Quindi, non può risolvere ": client_id" poiché l'identificatore reale è "form_id: client_id". Ma dovrebbe essere rivisto in quanto ho perso l'attenzione su JSF durante i 2 anni passati. –

+0

Quindi, sì, l'arlgoritmo componentSEarch richiede il percorso completo per un componente. Non sai se è una cosa specifica per l'implementazione di Mojarra? –

Problemi correlati