У меня проблема с JSF, надеюсь, кто-нибудь может мне помочь.
У меня есть страница Facelets XHTML с управляемым компонентом SessionScoped. Когда на странице нажата командная кнопка, в компоненте вызывается метод, который динамически создает другую форму на странице с другой командной кнопкой. Пока это работает очень хорошо, но когда на странице нажимают только что созданную кнопку, она как-то дважды вызывает метод действия.
Вот примеры кода из моего бина:
Метод, который динамически создает новую форму и работает нормально: (я использовал 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>
Я только начал изучать jsf, так что, возможно, я делаю что-то действительно неправильно, но я был бы очень благодарен, если бы кто-то мог объяснить это.
Спасибо