2012-08-25 17 views
16

¿Tiene JSF 2.0 un método integrado para encontrar el ID de cliente de otro componente? Hay aproximadamente mil preguntas relacionadas con ID de cliente en SO y hay muchos métodos de hackeo para hacerlo, pero me pregunto si JSF 2.0 trajo un método más simple que simplemente no sé.Recuperando el ID de cliente de otro componente en JSF 2.0

#{component.clientId} evalúa el ID de cliente de un componente determinado, pero quiero hacer referencia al ID de otro componente.

This publicación de blog menciona component.clientId, y también dice #{someComponent.clientId} funciona, pero por lo que puedo decir que no. Creo que él escribió eso antes de que las implementaciones de referencia de JSF 2.0 salieran, por lo que solo estaba pasando por el JSR y tal vez esa funcionalidad cambió. No estoy seguro.

Sé que PrimeFaces y RichFaces tienen sus propias funciones para devolver un ID de cliente, pero me pregunto si hay un método JSF 2.0 incorporado para esto. He aquí algunos ejemplos:

Esto funciona para devolver el ID del outputText.

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

De acuerdo con el blog anteriormente, esto debería funcionar, pero no es así. Simplemente no obtengo salida.

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

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

Esto funciona en PrimeFaces:

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

Obras en RichFaces:

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

También, si es posible que estoy buscando soluciones que ganaron' romper si cambio el valor de javax.faces.SEPARATOR_CHAR o si agrego/quito contenedores fuera de la referencia componentes. He pasado mucho tiempo rastreando los problemas causados ​​por las rutas de identificación codificadas.

Respuesta

28

Debe asignarle al componente un nombre de variable en el alcance de la vista por el atributo binding.

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

Eso es genial. Supuse que el atributo 'binding' era exclusivamente para exponer componentes a respaldos de beans; no me di cuenta de que también podías publicar un componente en el alcance. Muchas gracias. – cutchin

+0

De nada. – BalusC

+0

¡Tampoco sabía que podrías hacer eso! No había visto referencias en documentos para ese uso de binding/EL. ¿Es esto nuevo en JSF 2.x? (es decir, ¿está también disponible en 1.2?) –

1

Esto funcionó para mí. Sin embargo, me gustaría saber si está bien escribir una respuesta como esta.

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

ya que este fue uno de los primeros resultados de mi búsqueda de google y me preguntó por qué me dieron un javax

. el.PropertyNotFoundException (Propiedad 'itemId' no encontrado [...])

al intentar la solución aceptada, me gustaría compartir mi solución para JSF 1.2:

El método UIComponentgetClientId necesita un parámetro FacesContext (ver UIComponent documentation). Así que agregar un enlace al bean de respaldo y también otro método que devuelve la 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); 
} 

en cuenta que el grano va a enlazar el componente para debiera solicite el alcance o de lo contrario podría terminar con un java.lang.IllegalStateException (duplicate Id for a component) (compare con this topic).

Cuestiones relacionadas