JSF 2.0 命令按钮操作被调用两次
我在使用 JSF 时遇到了问题,希望有人能帮助我。 我有一个 Facelets xhtml 页面,带有 SessionScoped 托管 bean。当在页面上按下命令按钮时,会在 bean 中调用一个方法,该方法会在页面上动态创建另一个带有另一个命令按钮的表单。到目前为止,效果很好,但是当在页面上按下新创建的按钮时,它会以某种方式调用操作方法两次。 以下是我的支持 bean 中的代码示例:
动态创建新表单并且工作正常的方法:(我使用 setActionExpression 将操作绑定到按钮)
public void doCreateScreen() {
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
panelGrid.getChildren().clear();
HtmlPanelGrid checkBoxGrid = (HtmlPanelGrid) application
.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
checkBoxGrid.setColumns(columnNumber + 1);
checkBoxGrid.getChildren().clear();
for (int i = 1; i < rowNumber + 1; i++) {
for (int j = 1; j < columnNumber + 1; j++) {
HtmlSelectBooleanCheckbox tmpCheckBox = (HtmlSelectBooleanCheckbox) application
.createComponent(HtmlSelectBooleanCheckbox.COMPONENT_TYPE);
String id = String.valueOf(i * columnNumber + j);
tmpCheckBox.setId("box" + id);
tmpCheckBox.setValue(true);
checkBoxGrid.getChildren().add(tmpCheckBox);
}
}
HtmlCommandButton createSeatsButton = (HtmlCommandButton) application
.createComponent(HtmlCommandButton.COMPONENT_TYPE);
createSeatsButton.setValue("Create Screen");
MethodExpression createSeats = application.getExpressionFactory()
.createMethodExpression(context.getELContext(),
"#{screencontroller.doCreateSeats}", null,
new Class<?>[0]);
createSeatsButton.setActionExpression(createSeats);
panelGrid.getChildren().add(checkBoxGrid);
panelGrid.getChildren().add(createSeatsButton);
}
这个方法被调用两次:
public void doCreateSeats() {
try {
screen = screenOperator.createScreen(screen);
for (int i = 1; i < rowNumber + 1; i++) {
for (int j = 1; j < columnNumber + 1; j++) {
Seat seat = new Seat();
seat.setRow(i);
seat.setSeatNumber(j);
seat = screenOperator.createSeat(seat,
screen.getIdScreen());
}
}
panelGrid.getChildren().clear();
} catch (MovieTicketsException e) {
// TODO
e.printStackTrace();
}
}
以及 xhtml 源:
<div class="addform">
<h1>Add new screen</h1>
<h:form prependId="false">
<h:panelGrid columns="2">
<h:outputText value="Description:"></h:outputText>
<h:inputText value="#{screencontroller.screen.description}"
title="Description" id="Description" required="true"
class="inputfield">
<f:validateLength minimum="1" maximum="255"></f:validateLength>
</h:inputText>
<h:outputText value="Rows:"></h:outputText>
<h:selectOneMenu value="#{screencontroller.rowNumber}" title="Rows"
id="Rows" required="true" class="inputfield">
<f:selectItems value="#{screencontroller.rowsSelectItems}">
</f:selectItems>
</h:selectOneMenu>
<h:outputText value="Seats in a row:"></h:outputText>
<h:selectOneMenu value="#{screencontroller.columnNumber}"
title="Columns" id="Columns" required="true" class="inputfield">
<f:selectItems value="#{screencontroller.rowsSelectItems}">
</f:selectItems>
</h:selectOneMenu>
<h:outputLabel></h:outputLabel>
<h:commandButton action="#{screencontroller.doCreateScreen}"
value="Submit"></h:commandButton>
</h:panelGrid>
</h:form> <h:message for="Description" class="errormsg"></h:message> <h:message
for="Cinema" class="errormsg"></h:message></div>
<div class="listdiv"><h:form prependId="false">
<h:panelGrid binding="#{screencontroller.panelGrid}" columns="1">
</h:panelGrid>
</h:form></div>
</div>
I'我刚刚开始学习 jsf,所以也许我做的事情真的错了,但如果有人能解释这一点,我将非常感激。
谢谢
I got a problem with JSF, hope someone can help me out.
I have a Facelets xhtml page, with a SessionScoped managed bean. When a commandbutton is pressed on the page, a method is invoked in the bean, which dinamically creates another form on the page, with another commandbutton. That works very well so far, but when the newly created button is pressed on the page it somehow calls the action method twice.
Here are the code samples from my backing bean:
The method which dynamically creates the new form, and works fine: (I used setActionExpression to bind an action to the button)
public void doCreateScreen() {
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
panelGrid.getChildren().clear();
HtmlPanelGrid checkBoxGrid = (HtmlPanelGrid) application
.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
checkBoxGrid.setColumns(columnNumber + 1);
checkBoxGrid.getChildren().clear();
for (int i = 1; i < rowNumber + 1; i++) {
for (int j = 1; j < columnNumber + 1; j++) {
HtmlSelectBooleanCheckbox tmpCheckBox = (HtmlSelectBooleanCheckbox) application
.createComponent(HtmlSelectBooleanCheckbox.COMPONENT_TYPE);
String id = String.valueOf(i * columnNumber + j);
tmpCheckBox.setId("box" + id);
tmpCheckBox.setValue(true);
checkBoxGrid.getChildren().add(tmpCheckBox);
}
}
HtmlCommandButton createSeatsButton = (HtmlCommandButton) application
.createComponent(HtmlCommandButton.COMPONENT_TYPE);
createSeatsButton.setValue("Create Screen");
MethodExpression createSeats = application.getExpressionFactory()
.createMethodExpression(context.getELContext(),
"#{screencontroller.doCreateSeats}", null,
new Class<?>[0]);
createSeatsButton.setActionExpression(createSeats);
panelGrid.getChildren().add(checkBoxGrid);
panelGrid.getChildren().add(createSeatsButton);
}
And this method which is called twice:
public void doCreateSeats() {
try {
screen = screenOperator.createScreen(screen);
for (int i = 1; i < rowNumber + 1; i++) {
for (int j = 1; j < columnNumber + 1; j++) {
Seat seat = new Seat();
seat.setRow(i);
seat.setSeatNumber(j);
seat = screenOperator.createSeat(seat,
screen.getIdScreen());
}
}
panelGrid.getChildren().clear();
} catch (MovieTicketsException e) {
// TODO
e.printStackTrace();
}
}
And the xhtml source:
<div class="addform">
<h1>Add new screen</h1>
<h:form prependId="false">
<h:panelGrid columns="2">
<h:outputText value="Description:"></h:outputText>
<h:inputText value="#{screencontroller.screen.description}"
title="Description" id="Description" required="true"
class="inputfield">
<f:validateLength minimum="1" maximum="255"></f:validateLength>
</h:inputText>
<h:outputText value="Rows:"></h:outputText>
<h:selectOneMenu value="#{screencontroller.rowNumber}" title="Rows"
id="Rows" required="true" class="inputfield">
<f:selectItems value="#{screencontroller.rowsSelectItems}">
</f:selectItems>
</h:selectOneMenu>
<h:outputText value="Seats in a row:"></h:outputText>
<h:selectOneMenu value="#{screencontroller.columnNumber}"
title="Columns" id="Columns" required="true" class="inputfield">
<f:selectItems value="#{screencontroller.rowsSelectItems}">
</f:selectItems>
</h:selectOneMenu>
<h:outputLabel></h:outputLabel>
<h:commandButton action="#{screencontroller.doCreateScreen}"
value="Submit"></h:commandButton>
</h:panelGrid>
</h:form> <h:message for="Description" class="errormsg"></h:message> <h:message
for="Cinema" class="errormsg"></h:message></div>
<div class="listdiv"><h:form prependId="false">
<h:panelGrid binding="#{screencontroller.panelGrid}" columns="1">
</h:panelGrid>
</h:form></div>
</div>
I've just started learning jsf, so maybe i'm doing somthing really wrong, but i would be very thankful if someone could explain this.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论