2012-08-25 7 views
16

JSF 2.0 ha un metodo integrato per trovare l'ID client di un altro componente? Ci sono circa mille domande relative all'ID client su SO e ci sono un sacco di metodi hacker per farlo, ma mi chiedo se JSF 2.0 abbia portato un metodo più semplice che io non conosco.Recupero dell'ID client di un altro componente in JSF 2.0

#{component.clientId} valuta l'ID cliente di un determinato componente, ma desidero fare riferimento all'ID di un altro componente.

This post di blog menziona component.clientId, e anche dice #{someComponent.clientId} funziona, ma da quello che posso dire che non lo fa. Credo che l'abbia scritto prima che tutte le implementazioni di riferimento di JSF 2.0 fossero fuori, quindi stava semplicemente passando per la JSR e forse quella funzionalità è cambiata. Non ne sono sicuro.

So che PrimeFaces e RichFaces hanno entrambe le proprie funzioni per restituire un ID client, ma mi chiedo solo se esiste un metodo JSF 2.0 integrato per questo. Ecco alcuni esempi:

Questo funziona per restituire l'ID del outputText.

`<h:outputText value="My client ID : #{component.clientId}" />` 

Secondo il post di cui sopra, questo dovrebbe funzionare, ma non è così. Non ottengo output.

`<h:button id="sampleButton" value="Sample" />` 

`<h:outputText value="sampleButton's client ID : #{sampleButton.clientId}" />` 

Questo funziona in primefaces:

`<h:outputText value="PrimeFaces : sampleButton's client ID : #{p:component('sampleButton')}" />` 

Opere in RichFaces:

`<h:outputText value="RichFaces : sampleButton's client ID : #{rich:clientId('sampleButton')}" />` 

Inoltre, se possibile Sto cercando soluzioni che hanno vinto' rompere se cambio il valore javax.faces.SEPARATOR_CHAR o se aggiungo/rimuovo i contenitori al di fuori del riferimento componenti. Ho dedicato molto tempo a rintracciare i problemi causati da percorsi ID codificati.

risposta

28

È necessario assegnare al componente un nome di variabile nello scope vista mediante l'attributo binding.

<h:button id="sampleButton" binding="#{sampleButton}" value="Sample" /> 
<h:outputText value="sampleButton's client ID : #{sampleButton.clientId}" /> 
+3

È grandioso. Supponevo che l'attributo 'binding' fosse esclusivamente per l'esposizione dei componenti ai bean backing - Non mi ero reso conto che potevi anche pubblicare un componente sull'oscilloscopio. Grazie mille. – cutchin

+0

Prego. – BalusC

+0

Inoltre non sapevo che potessi farlo! Non avevo visto alcun riferimento nei documenti a quell'uso di binding/EL. È nuovo in JSF 2.x? (cioè è disponibile anche in 1.2?) –

1

Questo ha funzionato per me. Sarei interessato a sapere se è OK scrivere una risposta come questa però.

client.html

<h:outputText value="#{UIHelper.clientId('look-up-address-panel-id')}" /> 

UIHelper.java

@ManagedBean(name = "UIHelper", eager = true) 
@ApplicationScoped 
public class UIHelper 
{ 

public String clientId(final String id) 
{ 
    FacesContext context = FacesContext.getCurrentInstance(); 
    UIViewRoot root = context.getViewRoot(); 
    final UIComponent[] found = new UIComponent[1]; 
    root.visitTree(new FullVisitContext(context), new VisitCallback() 
    { 
    @Override 
    public VisitResult visit(VisitContext context, UIComponent component) 
    { 
     if (component.getId().equals(id)) 
     { 
     found[0] = component; 
     return VisitResult.COMPLETE; 
     } 
     return VisitResult.ACCEPT; 
    } 
    }); 
    return found[0] == null ? "" : "#" + found[0].getClientId().replace(":", "\\\\:"); 
} 

} 
0

Dal momento che questo è stato tra i primi risultati della mia ricerca su google e mi chiedevo perché ho ottenuto un javax

. el.PropertyNotFoundException (proprietà 'itemId' non trovato [...])

quando si tenta la soluzione accettata, vorrei condividere la mia soluzione per JSF 1.2:

Il metodo UIComponentgetClientId richiede un parametro FacesContext (vedere UIComponent documentation). Quindi aggiungere un legame con il backing bean e anche un altro metodo che restituisce il clientId:

xhtml:

<h:button id="sampleButton" binding="#{backingBean.sampleButton}" value="Sample" /> 
<h:outputText value="sampleButton's client ID : #{backingBean.sampleButtonClientId}" /> 

Bean:

private UIComponent sampleButton; 

public UIComponent getSampleButton() { 
    return sampleButton; 
} 

public void setSampleButton(final UIComponent sampleButton) { 
    this.sampleButton = sampleButton; 
} 

public String getSampleButtonClientId() { 
    final FacesContext context = FacesContext.getCurrentInstance(); 
    return sampleButton.getClientId(context); 
} 

Si noti che il fagiolo si sono vincolanti il ​​componente a dovrebbe essere richiesta con scope oppure si potrebbe finire con un java.lang.IllegalStateException (duplicate Id for a component) (confrontare con this topic).