2012-01-13 7 views
16

Ho un modello e nella sua definizione utilizzo diversi moduli e pulsanti.Ottieni l'ID del contenitore di denominazione principale nel modello per l'attributo render/update

Il problema è la definizione (define) Il file xhtml non conosce la gerarchia dei componenti.

E ad esempio voglio aggiornare l'elemento "tabella2" in una forma diversa nello stesso file di definizione.

Template Inserire:

<p:tabView id="nav"> <!-- nav --> 
    <ui:insert name="content_nav">content navigation</ui:insert> 
</p:tabView> 

definisce il primo livello della mia gerarchia "nav"

Template definire:

<ui:define name="content_nav"> 
    <h:form id="form1"> <!-- nav:form1 --> 
     <h:dataTable id="table1"/> <!-- nav:form1:table1 --> 
     <p:inputText value="#{bean.value}"/> 
     <p:commandButton action="..." update="nav:form2:table2"/> 
    </h:form> 
    <h:form id="form2"> 
     <h:dataTable id="table2"/> <!-- nav:form2:table2 --> 
     <!-- other elements --> 
    </h:form> 
</ui:define> 

Nel mio definire parte io non voglio sapere " nav "!

Come posso fare questo? o come posso spostare un componente di denominazione verso l'alto? o salvare l'id completo genitore più alto in una variabile?

a volte ho visto qualcosa di simile:

update=":table2" 

ma non riuscivo a trovare nessuna informazione su questo ?, la documentazione JavaEE 6 appena cita le parole chiave @.

risposta

43

brutto, ma questo dovrebbe funzionare per voi:

<p:commandButton action="..." update=":#{component.namingContainer.parent.namingContainer.clientId}:form2:table2" /> 

Come si sta già utilizzando primefaces, in alternativa è quella di utilizzare #{p:component(componentId)}, questo helper scansioni funzione l'intera vista radice per un componente con l'ID specificato e quindi restituisce il suo ID cliente:

<p:commandButton action="..." update=":#{p:component('table2')}" /> 
+1

Grazie per la risposta. # {component.namingContainer.parent.namingContainer.clientId} funziona correttamente. Ma speravo in una soluzione più elegante (syntax sugar). Simile a "../" per le strutture di cartelle. Perché hai ancora scritto i due punti come prefisso? Sono nuovo di jsf quindi chiedo. E non penso che sia così brutto da quando usare il contenitore di nomi sconosciuto clientId direttamente è più brutto dato che potrei usare quel modello più volte. Penso che mi definirò una funzione EL per ottenere l'ID client di un contenitore di denominazione fratello. – djmj

+1

I due punti sono il carattere di separazione predefinito 'NamingContainer' (che è sovrascrivibile da un parametro di contesto). Quando lo si utilizza come prefisso, verrà interpretato come ID client "assoluto", vale a dire che è stato risolto relativamente a 'UIViewRoot' al posto dell'attuale' NamingContainer' (che può essere il composito, o datatable, o modulo, ecc.). Per quanto riguarda la soluzione migliore, usa invece la funzione 'p: component()' (o quella homebrew). – BalusC

+2

p: componente non funziona per me. Sono molto triste con questo comportamento JSF. Niente funziona. – MaikoID

0

Prova questo:

<h:commandButton value="Click me"> 
    <f:ajax event="click" render="table" /> 
</h:commandButton> 
+0

Non ero abbastanza preciso. Voglio aggiornare un particolare elemento con il suo id, poiché non tutti gli elementi sono nella stessa forma. Ho modificato il mio post per renderlo chiaro. Cosa fa esattamente @table? Se entrambi gli elementi sono fratelli, potrei semplicemente usare render = "table" senza @? – djmj

+0

Si potrebbe usare render = "table". –

+1

Che cos'è render = "table" ...? – Andrew

1

brutta risposta funziona bene

update=":#{component.namingContainer.parent.namingContainer.clientId}:form2:table2 

aggiornamento soprattutto più utile da finestra aperta al genitore DataTable

0

In aggiunta alle soluzioni sopra ho avuto il problema, che ho dovuto generare dinamicamente i componenti a-essere-aggiornamento (molti) in base alla logica lato server (con forse più difficile individuare l'annidamento).

Quindi la soluzione sul lato server è un equivalente a update=":#{p:component('table2')}" che utilizza org.primefaces.util.ComponentUtils.findComponentClientId(String designId):

// UiPnlSubId is an enum containing all the ids used within the webapp xhtml. 
// It could easily be substituted by a string list or similar. 
public static String getCompListSpaced(List<UiPnlSubId> compIds) { 

    if (compIds == null || compIds.isEmpty()) 
     return "" ; 
    StringBuffer sb = new StringBuffer(":") ; 
    for (UiPnlSubId cid : compIds) 
     sb.append(ComponentUtils.findComponentClientId(cid.name())).append(" ") ; 
    return sb.deleteCharAt(sb.length() - 1).toString() ; // delete suffixed space 
} 

chiamato attraverso qualche altro metodo utilizza, ad esempio come ... update="#{foo.getCompListComputed('triggeringCompId')}".

: prima ho cercato, senza troppo pensare di tornare public static String getCompListSpaced0() { return ":#{p:component('table2')}" ; } in un ... update="#{foo.getCompListSpaced0()} espressione, che naturalmente (dopo aver riflettuto su come funziona il quadro :)) non è risolto (restituito come è) e può causare i problemi con esso alcuni utenti hanno sperimentato. Anche il mio ambiente Eclipse/JBoss Tools suggeriva di scrivere :#{p.component('table2')} ("." Invece di ":") che non serviva - ovviamente.

0

È possibile utilizzare l'attributo binding per dichiarare la variabile EL associata al componente JSF. Quindi è possibile accedere all'ID client assoluto di questo componente utilizzando javax.faces.component.UIComponent.getClientId(). Vedere l'esempio di seguito:

<t:selectOneRadio 
    id="yourId" 
    layout="spread" 
    value="#{yourBean.value}" 
    binding="#{yourIdComponent}"> 
     <f:selectItems value="#{someBean.values}" /> 
</t:selectOneRadio> 
<h:outputText> 
    <t:radio for=":#{yourIdComponent.clientId}" index="0" /> 
</h:outputText> 
Problemi correlati