8

JSF を Web ページに動的に追加しようとして<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 式は、通常のビュー ファイルで使用するものとまったく同じであることに注意してください。


ここでの更新は、Tomcat 7.0.27 上の Mojarra 2.1.12 で問題なく動作する SSCCE です。

<!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 に答える