8

我正在尝试将 JSF<h:commandButtons>动态添加到我的网页中,到目前为止我已经显示了它们,但是我无法像在静态页面中那样使用参数设置操作:
action="#{bean.function(parameter)}". (这当然是使用 EL-2.2)
环顾四周,我发现我必须创建一个MethodExpression,但这对我来说是模糊的,我还没有找到很多关于这方面的信息。如果有人能在迷雾中发光并解释如何做到这一点,将不胜感激。

编辑:所以现在我有了这个

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

1 回答 1

19

使用ExpressionFactory#createMethodExpression().

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

这是一个方便的方法:

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

以下动作方法示例:

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)

然后可以按如下方式创建:

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

请注意,EL 表达式与您在普通视图文件中使用的完全相同。


更新这里是一个 SSCCE,它适用于我在 Tomcat 7.0.27 上的 Mojarra 2.1.12。

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

}

与具体问题无关,以上都是不好的做法。另请参阅JSF 中的“绑定”属性如何工作?何时以及如何使用它?

于 2012-08-23T19:55:41.830 回答