2012-08-23 18 views
7

Estoy tratando de agregar JSF <h:commandButtons> dinámicamente a mi página web, y hasta ahora los tengo mostrando, pero no puedo establecer la acción con parámetros, como pude en una estática página:
action="#{bean.function(parameter)}". (Esto es, por supuesto, utilizando EL-2.2)
Mirando a mi alrededor me parece que tengo que crear un MethodExpression, pero esto es oscuro para mí y no he podido encontrar mucha información sobre esto. Si alguien pudiera hacer brillar una luz a través de la niebla y explicar cómo se puede hacer esto, sería muy apreciado.Comandos de comando de JSF (2.0) dinámicos - acción de conjunto con argumentos

EDIT: por lo que ahora tiene este

public void displayNode(String childName){ 
//lots of messy code instantiating JSF components 

if(activeEmployee.getParent() != null){ 
     HtmlCommandButton parent = new HtmlCommandButton(); 
     HtmlOutputText parentLabel = new HtmlOutputText(); 

     parentLabel.setId("label" + count++); //I really hate having to use count 
     parentLabel.setValue("Parent: "); 

     parent.setId("Parent" + count++); 
     String parentName = activeEmployee.getParent().getName(); 
     parent.setValue(parentName); 
     MethodExpression expression = createMethodExpression("#{tree.displayNode('" + parentName + "')}", 
                   null, String.class); 
     parent.setActionExpression(expression); 

     newDiv.getChildren().add(parentLabel); 
     newDiv.getChildren().add(parent); 
    } 
+0

¿No puede usar la propiedad procesada para mostrar u ocultar el botón de comando? – RajV

+0

nah Estoy creando dinámicamente nodos de árbol con botones para mostrar otros nodos relacionados –

Respuesta

17

Uso ExpressionFactory#createMethodExpression().

public abstract MethodExpression createMethodExpression(
             ELContext context, 
             java.lang.String expression, 
             java.lang.Class<?> expectedReturnType, 
             java.lang.Class<?>[] expectedParamTypes) 

Aquí está un método de conveniencia:

public static MethodExpression createMethodExpression(String expression, Class<?> returnType, Class<?>... parameterTypes) { 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    return facesContext.getApplication().getExpressionFactory().createMethodExpression(
     facesContext.getELContext(), expression, returnType, parameterTypes); 
} 

Los siguientes ejemplos método de acción:

public void submit1() 
public String submit2() 
public void submit3(String argument) 
public String submit4(String argument) 
public void submit5(String argument1, Long argument2) 
public String submit6(Long argument1, String argument2) 

continuación, se pueden crear de la siguiente manera:

createMethodExpression("#{bean.submit1}", null); 
createMethodExpression("#{bean.submit2}", String.class); 
createMethodExpression("#{bean.submit3('foo')}", null, String.class); 
createMethodExpression("#{bean.submit4('foo')}", String.class, String.class); 
createMethodExpression("#{bean.submit5('foo', 0)}", null, String.class, Long.class); 
createMethodExpression("#{bean.submit6(0, 'foo')}", String.class, Long.class, String.class); 

Tenga en cuenta que la expresión EL es exactamente la misma que usaría en el archivo de vista normal.


actualización aquí hay un SSCCE que funciona muy bien para mí con Mojarra 2.1.12 en Tomcat 7.0.27.

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
> 
    <h:head> 
     <title>SO question 12098611</title> 
    </h:head> 
    <h:body> 
     <h:form binding="#{bean.form}"> 
      <h:commandButton value="add" action="#{bean.add}" /> 
     </h:form> 
    </h:body> 
</html> 
@ManagedBean 
@RequestScoped 
public class Bean { 

    private UIForm form; 

    public void add() { 
     String id = "button" + form.getChildCount(); 
     UICommand button = new HtmlCommandButton(); 
     button.setId(id); 
     button.setValue(id); 
     button.setActionExpression(createMethodExpression(String.format("#{bean.submit('%s')}", id), null, String.class)); 
     form.getChildren().add(button); 
    } 

    public void submit(String arg) { 
     System.out.println("submit: " + arg); 
    } 

    public UIForm getForm() { 
     return form; 
    } 

    public void setForm(UIForm form) { 
     this.form = form; 
    } 

    public static MethodExpression createMethodExpression(String expression, Class<?> returnType, Class<?>... parameterTypes) { 
     FacesContext facesContext = FacesContext.getCurrentInstance(); 
     return facesContext.getApplication().getExpressionFactory().createMethodExpression(
      facesContext.getELContext(), expression, returnType, parameterTypes); 
    } 

} 

Sin relación al problema concreto, todo lo anterior es una mala práctica. Consulte también How does the 'binding' attribute work in JSF? When and how should it be used?

+1

Una vez más, eres el hombre. Estaba buscando esta información en Internet porque la hice pero usando JSF 1.2. –

+0

Supongo que prematuramente asumí que necesitaba un 'MethodExpression' porque lo he visto antes de usar' button.setActionExpression (...) '. ¿Cuál es la diferencia entre usar 'setActionExpression()' y 'setAction()', además de los argumentos obvios requeridos? –

+1

@Jake: 'setAction()' es la [obsoleta] (http://docs.oracle.com/javaee/6/api/javax/faces/component/UICommand.html#setAction (javax.faces.el.MethodBinding))) sobras de JSF 1.x utilizando "EL diferido", que utilizó su propia implementación EL con 'ValueBinding',' MethodBinding' y más (que luego se unificó con JSP EL). ** No ** usa ninguna API en desuso en JSF 2.x en absoluto. Ellos están sujetos a remoción. Ver también http://stackoverflow.com/questions/4812755/difference-between-jsp-el-jsf-el-and-unified-el para un poco de historia sobre EL. – BalusC

Cuestiones relacionadas