我正在尝试动态地将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 );
}
答案 0 :(得分:17)
使用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);
}
}
无关,以上所有都是不好的做法。另请参阅How does the 'binding' attribute work in JSF? When and how should it be used?