我试图让MenuItem
[在Menubar
内]发出ActionEvent
并在按下时调用方法,但是,从不调用监听方法,而我不明白为什么:
xhtml页面:
<h:body>
<h:form>
<p:menubar model="#{testBean.model}" />
<h:commandButton value="submit" />
<h:outputText value="#{testBean.confirmation}" />
</h:form>
</h:body>
</html>
jsf bean:
@ManagedBean
public class TestBean implements ActionListener{
MenuModel model = new DefaultMenuModel();
private String confirmation = "negative";
public TestBean() {
MenuItem item = new MenuItem();
item.setValue("Click");
item.setUrl("#");
item.addActionListener(this);
model.addMenuItem(item);
}
@Override
public void processAction(ActionEvent event)
throws AbortProcessingException {
// EXECUTION NEVER REACHES HERE!
confirmation = "positive";
}
public MenuModel getModel() {
return model;
}
public String getConfirmation() {
return confirmation;
}
}
可视化非常简单的输出可能有所帮助:
我正在使用Primefaces 3.1.0和JSF 2.0
答案 0 :(得分:3)
我的第一个建议是向你的动作监听器添加某种调试日志记录,以便找出它是否被调用。如果它被调用但您的网站没有呈现更改,则可能是由于以下原因。
@ViewScoped
或@SessionScoped
管理中。 顺便说一下,我们没有实施ActionListener
。我们将方法表达式分配给菜单项。这是一个简短的模型示例:我们使用菜单项的操作来切换上下文菜单的按钮状态。希望我能以某种方式帮助你。
Facelet代码段:
<p:menu model="#{menuBean.model}" />
Bean片段:
@ManagedBean
@ViewScoped
public class MenuBean implements Serializable {
private MenuModel model;
private boolean cutAllowed = false;
/** Creates a new instance of MenuBean */
public MenuBean() {
model = new DefaultMenuModel();
//First submenu
Submenu submenu = new Submenu();
submenu.setLabel("Dynamic Submenu 1");
MenuItem item = new MenuItem();
item.setValue("toggle");
item.setUpdate("contextMenu");
item.setAjax(true);
item.setIcon("ui-icon ui-icon-disk");
ExpressionFactory factory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
MethodExpression methodExpression = factory.createMethodExpression(FacesContext.getCurrentInstance().getELContext(), "#{menuBean.toggleCutState}", String.class, new Class[]{});
item.setActionExpression(methodExpression);
submenu.getChildren().add(item);
model.addSubmenu(submenu);
}
public boolean isCutAllowed() {
return cutAllowed;
}
public void setCutAllowed(boolean cutAllowed) {
this.cutAllowed = cutAllowed;
}
public String toggleCutState() {
toggleCutState(null);
return null;
}
public void toggleCutState(ActionEvent event) {
this.cutAllowed = !this.cutAllowed;
System.out.println("toggle called");
}
public MenuModel getModel() {
return model;
}
}
答案 1 :(得分:1)
原始代码的第一个问题是我需要一个唯一的ID。我很早就发现了这一点,但它导致了另一个非常恼人的问题:将调用动作侦听器,但页面不会更新。要解决此问题(如here所述),您可以在MenuItem上禁用ajax或自定义更新方式。
正确的构造函数代码是:
public TestBean() {
MenuItem item = new MenuItem();
item.setValue("Click");
// New code:
item.setId(FacesContext.getCurrentInstance().getViewRoot().createUniqueId());
item.setAjax(false);
item.setUrl("#");
item.addActionListener(this);
model.addMenuItem(item);
}
答案 2 :(得分:1)
@Mogwli,item.setId((new UiViewRoot())。createUniqueId());因为新的UIViewRoot()不能识别上下文,所以会导致IllegalArgumentException ...应该是item.setId(FacesContext.getCurrentInstance()。getViewRoot()。createUniqueId());
答案 3 :(得分:0)
首先,您的代码段显示<h:commandButton>
不 Primefaces commandButton <p:commandButton>
。
其次,您没有指定commandButton的actionListener
属性指向processAction
。
<p:commandButton value="submit" actionListener="#{testBean.processAction}" />