问题
I'm updating a project from Primefaces 3.5 to 4.0 and I've got problem with menu. I can't understand how to create dynamically a simple menu like this:
<p:menu>
<p:submenu>
<p:menuitem value="jump" action="myTransition" />
</p:submenu>
</p:menu>
I try to set the command of the item with the name of the transition, defined in my Spring web flow configuration, with no result.
DefaultMenuItem itemNone = new DefaultMenuItem();
item.setCommand("myTransition");
The plain menu work fine, but if I try the dynamic one the page just refresh, no errors or other evidence.
So, basically I need to port this code, from pf 3.5 to pf >4.0
for(String elem : list)
{
MenuItem item = new MenuItem();
item.setValue(elem.toUpperCase());
item.setActionExpression(CommonUtils.createMethodExpressionInUIContext(FacesContext.getCurrentInstance(), elem.replaceAll("\\s","").replace(".", ""),
String.class, new Class[]{String.class}));
submenu.getChildren().add(item);
}
with this function
public static MethodExpression createMethodExpressionInUIContext(final FacesContext facesContext, final String expression, Class<?> class1, Class[] classes) {
FaceletContext faceletElContext = (FaceletContext) FacesContext.getCurrentInstance().getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
MethodExpression methodExpression = FacesContext.getCurrentInstance().getApplication().getExpressionFactory()
.createMethodExpression(faceletElContext, expression, class1, classes);
return methodExpression;
}
My try with
DefaultMenuItem item = new DefaultMenuItem();
item.setCommand(elem);
or
item.setCommand(CommonUtils.createMethodExpressionInUIContext(FacesContext.getCurrentInstance(), elem.replaceAll("\\s","").replace(".", ""),String.class, new Class[]{String.class}).getExpressionString());
didn't work
回答1:
Just to myself, from the past, to achieve my goal I followed these steps:
- register my own Menu and MenuRenderer, that extends Primefaces version
- define a new MenuItem with an additional field, for action command (named commandAction)
- Override decode method as:
MenuRenderer
@Override
public void decode(FacesContext context, UIComponent component) {
AbstractMenu menu = (AbstractMenu) component;
String clientId = menu.getClientId(context);
Map<String, String> params = context.getExternalContext().getRequestParameterMap();
if (params.containsKey(clientId)) {
String menuid = params.get(clientId + "_menuid");
DefaultMenuItem menuitem = (DefaultMenuItem) findMenuitem(menu.getElements(), menuid);
MenuActionEvent event = new MenuActionEvent(menuitem, menuitem);
// Action Listener
if (StringUtils.isNoneBlank(menuitem.getCommand())) {
menuitem.setActionExpression(CommonUtils.createMethodExpressionInUIContext(
FacesContext.getCurrentInstance(), menuitem.getCommand().replaceAll("\\s", "").replace(".", ""),
String.class, new Class[] { String.class }));
if (menuitem.isImmediate()) {
event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
} else {
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
}
menu.queueEvent(event);
}
// Action
if (StringUtils.isNoneBlank(menuitem.getCommandAction())) {
menuitem.setActionExpression(CommonUtils.createMethodExpressionInUIContext(
FacesContext.getCurrentInstance(), menuitem.getCommandAction().replaceAll("\\s", "").replace(".", ""),
String.class, new Class[] { String.class }));
if (menuitem.isImmediate()) {
event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
} else {
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
}
menu.queueEvent(event);
}
}
}
来源:https://stackoverflow.com/questions/59364383/dynamic-pmenu-works-in-primefaces-3-5-not-in-4-0