我正在尝试以编程方式创建一个HtmlCommandButton,遵循此处的示例
http://javaevangelist.blogspot.ch/2013/01/jsf-21-tip-of-day-programmatically.html
一切正常(即,调用actionListener)如果我添加ajax行为,如果关闭ajax它不起作用。
支持豆:
@Named
@RequestScoped
public class CommandBean implements Serializable {
public String generateUUID() {
return java.util.UUID.randomUUID().toString();
}
}
解决方案1(使用ajax)
private HtmlCommandButton createCommandButtonWithAjax(final FacesContext context,
final String methodExpression, final String value) {
Application application = context.getApplication();
Class<?>[] clazz = new Class<?>[]{};
HtmlCommandButton htmlCommandButton =
(HtmlCommandButton) application.createComponent(HtmlCommandButton.COMPONENT_TYPE);
htmlCommandButton.setValue(value);
AjaxBehavior ajaxBehavior = (AjaxBehavior) FacesContext.getCurrentInstance().getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
((UIComponentBase)htmlCommandButton).addClientBehavior("click", ajaxBehavior);
MethodExpression actionListener = application.getExpressionFactory().createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, String.class, clazz);
button.addActionListener(new MethodExpressionActionListener(actionListener));
return htmlCommandButton;
}
那个Chion 2(没有Ajax)
private HtmlCommandButton createCommandButton(final FacesContext context,
final String methodExpression, final String value) {
Application application = context.getApplication();
Class<?>[] clazz = new Class<?>[]{};
HtmlCommandButton htmlCommandButton =
(HtmlCommandButton) application.createComponent(HtmlCommandButton.COMPONENT_TYPE);
htmlCommandButton.setValue(value);
htmlCommandButton.setActionExpression(JSFUtils.createMethodExpression(methodExpression, String.class, clazz));
return htmlCommandButton;
}
来电代码:
createCommandButton(FacesContext.getCurrentInstance(),
"#{commandBean.generateUUID()}", "Generate UUID");
JSFUtils:
public static MethodExpression createMethodExpression(String methodExpression,Class<?> expectedReturnType,Class<?>[] expectedParamTypes) {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().getExpressionFactory()
.createMethodExpression(context.getELContext(), methodExpression, expectedReturnType, expectedParamTypes);
}
解决方案1正在工作,解决方案2没有:bean方法generateUUID()未被调用。我也尝试过htmlCommandButton.setImmediate(true)
来排除验证错误。
显然我们需要一个自定义AjaxBehavior,如下所示:https://forum.primefaces.org/viewtopic.php?f=3&t=5344和这里How to programmatically add an AjaxBehavior to a UIComponent with primefaces
自定义Ajax:
import java.util.HashMap;
import javax.el.ELContext;
import javax.el.MethodExpression;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.BehaviorEvent;
public class MyAjaxBehavior extends AjaxBehavior{
@Override
public Object saveState(FacesContext context) {
HashMap<String, Object> map;
map = new HashMap<String, Object>();
map.put( "update", getUpdate() );
map.put( "process", getProcess() );
map.put( "oncomplete", getOncomplete() );
map.put( "onerror", getOnerror() );
map.put( "onsuccess", getOnsuccess() );
map.put( "onstart", getOnstart() );
map.put( "listener", getListener() );
if (initialStateMarked()) return null;
return UIComponentBase.saveAttachedState(context, map);
}
@SuppressWarnings("unchecked")
@Override
public void restoreState(FacesContext context, Object state) {
if (state != null){
HashMap<String, Object> map;
map = (HashMap<String, Object>) UIComponentBase.restoreAttachedState(context, state);
setUpdate( (String) map.get( "update" ));
setProcess( (String) map.get( "process"));
setOncomplete( (String) map.get( "oncomplete" ));
setOnerror( (String) map.get( "onerror" ));
setOnsuccess( (String) map.get( "onsuccess" ));
setOnstart( (String) map.get( "onstart" ));
setListener( (MethodExpression) map.get( "listener" ));
}
}
@Override
public void broadcast(BehaviorEvent event) throws AbortProcessingException {
ELContext eLContext = FacesContext.getCurrentInstance().getELContext();
//Backward compatible implementation of listener invocation
if(getListener() != null) {
try {
getListener().invoke(eLContext, new Object[]{event});
} catch(IllegalArgumentException exception) {
getListener().invoke(eLContext, new Object[0]);
}
}
}
}
创建按钮
private HtmlCommandButton createCommandButtonWithAjax(final FacesContext context,
final String methodExpression, final String value) {
Application application = context.getApplication();
Class<?>[] clazz = new Class<?>[]{};
HtmlCommandButton htmlCommandButton =
(HtmlCommandButton) application.createComponent(HtmlCommandButton.COMPONENT_TYPE);
htmlCommandButton.setValue(value);
addPrimefacesAjaxSupport(htmlCommandButton,"click", methodExpression);
return htmlCommandButton;
}
添加AjaxBehavior
private AjaxBehavior addPrimefacesAjaxSupport(UIComponentBase comp, String event, String actionListener){
MyAjaxBehavior ajaxBehavior = new MyAjaxBehavior();
ajaxBehavior.setListener( JSFUtils.createMethodExpression(actionListener, void.class,new Class[]{ ActionEvent.class}) );
ajaxBehavior.setProcess( "@this" );
comp.addClientBehavior( event, ajaxBehavior );
return ajaxBehavior;
}