1

我正在使用JSF 1.2RichFaces 3.3.3。我在使用 Twitter Bootstrap 设计的页面上工作。我需要处理这样的订单操作:

  1. 用户点击页面上的操作按钮,
  2. 一个模态对话框打开并要求用户确认操作(如果用户取消操作,过程当然在这里结束),
  3. 在确认的情况下,对话框的内容从确认文本更改为其他一些内容以遵循操作处理(在某些情况下显示进度条,例如,在代码中只是一个等待文本),
  4. 操作完成后,对话框消失。

所以我需要同时做两件事,交替对话内容并在页面bean中启动一个动作。今天,我可以更改对话内容,但未处理在我的 bean 中启动的操作...为此,我在我的 bean 中使用一个标志来切换对话内容,由 a4j:support 修改a4j:commandButton 中的 onclick (在正常调用的操作之前执行)执行操作。

<a4j:commandButton 
    type="button"
    value="#{common.COMMON_Confirm}"
    styleClass="btn btn-danger"
    action="#{orderDetailBean.cancelOrder}"
    oncomplete="showCancelOrderModal(false);">
    <a4j:support 
        event="onclick" 
        actionListener="#{orderDetailBean.startProcessingMainAction}"
        reRender="cancelOrderForm" />
</a4j:commandButton>

也许这种方法是错误的……我只成功地完成了一次!现在我花了很多时间让它再次工作,一些帮助应该很好。请注意,我自几周以来就自学了 JSF 和 RichFaces。

现在,代码。

在我的网页的一些代码下面,首先是启动进程的按钮(通过 javascript 函数打开对话框),然后是 Twitter Bootstrap 对话框本身。

<!-- Main action button -->
<h:form>
    <a4j:commandButton 
        id="cancelOrder"
        styleClass="btn btn-danger btn-large"
        style="width: 100%; margin-bottom: 7px;"
        value="#{app.ACTION_OrderCancel}"
        oncomplete="showCancelOrderModal(true);"
        reRender="cancelOrderForm" />
</h:form>

<script type="text/javascript">
    function showCancelOrderModal(visible) {
        jQuery( function($) {
            $('#cancelOrderModal').modal(visible ? 'show' : 'hide');
        });
    }
</script>

<!-- Cancel order modal -->
<div class="modal modal-narrow modal-small hide fade" id="cancelOrderModal">
    <div class="modal-header">
        <h3>
            <h:outputText value="#{app.MODAL_CancelOrderTitle}" />
        </h3>
    </div>
    <a4j:form id="cancelOrderForm">
        <a4j:outputPanel 
            id="cancelOrderConfirm"
            rendered="#{!orderDetailBean.processingAction}">
            <div class="modal-body">
                <p>
                    <h:outputText value="#{app.MODAL_CancelOrderConfirm}" />
                </p>
            </div>
            <div class="modal-footer">
                <a href="#" 
                    class="btn btn-primary" 
                    data-dismiss="modal">
                    #{common.COMMON_Cancel}
                </a>
                <a4j:commandButton 
                    type="button"
                    value="#{common.COMMON_Confirm}"
                    styleClass="btn btn-danger"
                    action="#{orderDetailBean.cancelOrder}"
                    oncomplete="showCancelOrderModal(false);">
                    <a4j:support 
                        event="onclick" 
                        actionListener="#{orderDetailBean.startProcessingMainAction}"
                        reRender="cancelOrderForm" />
                </a4j:commandButton>
            </div>
        </a4j:outputPanel>
        <a4j:outputPanel 
            id="cancelOrderWait"
            rendered="#{orderDetailBean.processingAction}">
            <div class="modal-body">
                <h:outputText value="#{app.MODAL_CancelWait}" />
            </div>
        </a4j:outputPanel>
        <a4j:poll 
            id="cancelOrderPoll"
            interval="1000"
            enabled="#{orderDetailBean.processingAction}"
            reRender="cancelOrderPoll, cancelOrderWait" />
    </a4j:form>
</div>

和我的 bean 中的代码

private boolean processingAction;

public void startProcessingMainAction(ActionEvent event) {
    logger.debug("Set processing order main action to TRUE");
    processingAction = true;
}

public String cancelOrder() {
    logger.debug("Start to cancel order with id " + order.getId());
    try {
        processingAction = true;
        cancelProductionOrder(order.getId());
    }
    catch (Exception e) {
        logger.error("Unable to cancel production order" + order.getId(), e);
        addErrorMessage("An error occured cancelling order: " + e.getMessage(), null);
        return "error";
    }
    finally {
        processingAction = false;
    }
    return "";
}

那么,执行时会发生什么?

对话框正在打开,在用户确认后对话框内容交替出现(所以 a4j:support 效果很好),但是因为没有调用 a4j:commandButton 操作,它的 oncomplete 立即执行并且我的对话框消失了。

我希望你能帮助我,这是我 UI 的重要组成部分,截止日期是周末 ^_^


更新我观察到一个随机行为。很少(现在 2 次),但有时,一切正常,并且在 99% 时不会调用 commandButton 的操作:/

4

1 回答 1

1

操作完成后,您将重新呈现整个表单<a4j:support>。这样,表单的 HTML DOM 树将被丢弃并替换为来自 ajax 响应的树。<a4j:commandButton>这几乎与需要执行的默认操作同时发生。这里有竞争条件的手段。如果它发生默认操作将被执行之前,那么它将永远不会被执行,因为源已经完全消失了。

具体的功能要求并不完全清楚,因为startProcessingMainAction()在给定的示例中没有任何意义,它似乎完全是多余的。但我认为您可以通过将reRender属性从移动<a4j:support>到来解决它<a4j:commandButton>,以便仅在默认操作完成时重新渲染它。或者更好的是,<a4j:support>完全删除它,你似乎根本不需要它。

于 2012-06-27T13:04:20.700 回答