JSF 2.0 命令按钮操作被调用两次

发布于 2024-10-29 03:31:56 字数 4506 浏览 0 评论 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文