2012-08-23 5 views
7

Ich versuche, JSF <h:commandButtons> dynamisch zu meiner Webseite hinzuzufügen, und bis jetzt habe ich sie anzeigen, aber ich kann die Aktion nicht mit Parametern einstellen, wie ich in einer statischen könnte Seite:
action="#{bean.function(parameter)}". (Dies ist natürlich mit EL-2.2)
Um mich zu finden finde ich, dass ich eine MethodExpression erstellen muss, aber das ist mir unklar und ich konnte nicht viele Informationen dazu finden. Wenn jemand Licht durch den Nebel strahlen und erklären könnte, wie das gemacht werden kann, wäre es sehr zu schätzen.Dynamische JSF (2.0) commandButtons - Aktion mit Argumenten setzen

EDIT: so jetzt habe ich diese

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

Können Sie die gerenderte Eigenschaft nicht zum Ein-/Ausblenden der Befehlsschaltfläche verwenden? – RajV

+0

nah Ich bin dynamisch erstellen Baumknoten mit Schaltflächen zum Anzeigen anderer verwandter Knoten –

Antwort

17

Verwendung ExpressionFactory#createMethodExpression().

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

Hier ist eine bequeme Methode:

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

Die folgenden Aktionsmethode Beispiele:

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) 

kann dann wie folgt erstellt werden:

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

Beachten Sie, dass der EL-Ausdruck genau dem entspricht, den Sie in der normalen Ansichtsdatei verwenden würden.


aktualisieren hier ein SSCCE die für mich mit Mojarra 2.1.12 auf Tomcat 7.0.27 gut funktioniert.

<!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); 
    } 

} 

Unrelated auf die konkrete Problem, die alle oben ist eine schlechte Praxis. Siehe auch How does the 'binding' attribute work in JSF? When and how should it be used?

+1

Noch einmal, du bist der Mann. Ich suchte nach dieser Information im Internet, weil ich es gemacht habe, aber JSF 1.2 verwendend. –

+0

Ich vermute ich habe vorzeitig angenommen, dass ich eine 'MethodExpression' brauche, weil ich es schon gesehen habe, bevor ich 'button.setActionExpression (...)' benutzt habe. Was ist der Unterschied zwischen der Verwendung von 'setActionExpression()' und 'setAction()', abgesehen von den offensichtlichen Argumenten, die benötigt werden? –

+1

@Jake: 'setAction()' ist die [veraltet] (http://docs.oracle.com/javaee/6/api/javax/faces/component/UICommand.html#setAction (javax.faces.el.MethodBinding)) Überbleibsel von JSF 1.x unter Verwendung von "deferred EL", die ihre eigene EL-Implementierung mit "ValueBinding", "MethodBinding" usw. verwendete (was später mit JSP EL vereinheitlicht wurde). Benutze überhaupt keine veraltete API in JSF 2.x **. Sie unterliegen der Löschung. Siehe auch http://stackoverflow.com/questions/4812755/difference-between-jsp-el-jsf-el-and-unified-el für ein bisschen Geschichte auf EL. – BalusC