1

私はJSF 1.2RichFaces 3.3.3を使用しています。Twitter Bootstrap を使用して設計されたページに取り組んでいます。次のような注文でアクションを処理する必要があります。

  1. ユーザーがページのアクション ボタンをクリックし、
  2. モーダル ダイアログが開き、ユーザーにアクションの確認を求めます (ユーザーがアクションをキャンセルした場合、プロセスはもちろんここで終了します)。
  3. 確認の場合、ダイアログの内容は確認テキストから他の内容に変化し、アクションの処理に従います (場合によっては、進行状況バーを表示します。このコードでは単に待機テキストを表示します)。
  4. アクションが完了すると、ダイアログは消えます。

そのため、同時に 2 つのことを行う必要があります。ダイアログの内容を交互に切り替え、ページ 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 を独学で学んでいます。

さて、コードです。

私のWebページのいくつかのコードの下に、最初にプロセスを起動するボタン(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>

そして、私の豆のコード

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%でコマンドボタンのアクションが呼び出されません:/

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 に答える