2012-06-27 94 views
0

我正在使用JSF 1.2RichFaces 3.3.3。我在使用Twitter Bootstrap設計的頁面上工作。我需要處理這樣的訂單上的一個動作:在網頁上的操作按鈕action not a4j:commandButton with a4j:support onclick event

  1. 用戶點擊,
  2. 一個模式對話框打開,並要求用戶確認操作(如果用戶取消操作,當然過程在這裏結束),
  3. 如果確認,對話框的內容會從確認文本更改爲其他內容以跟隨動作處理(在某些情況下,例如在代碼中顯示進度條簡單地等待文本),
  4. 當動作完成時,對話框消失。

所以我需要在同一時間做兩件事,交替對話內容並在頁面bean中啓動一個動作。今天,我可以使對話框內容改變,但在我的bean中啓動的動作未被處理... 爲此,我在我的bean中使用一個標誌來切換對話框內容,並由a4j修改:在執行動作的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> 

和代碼在我的豆

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:支持效果很好),但是因爲a4j:commandButton動作沒有被調用,所以它的oncomplete被立即執行,我的對話框消失。

我希望你能幫助我,這是我的UI的一個重要組成部分,截止日期是在本週結束^ _^


更新我觀察到一個隨機的行爲。很少(現在是2次),但有時候,所有工作都很好,並且在99%的命令按鈕動作不被調用時:/

+0

爲什麼你需要'startProcessingMainAction()'?這在給出的例子中是沒有意義的。 – BalusC

+0

也許你想實現類似於刪除按鈕[這個演示](http://livedemo.exadel.com/richfaces-demo/richfaces/dataTable.jsf?tab=editDataTable),但使用一個' '。此外,還有一個基於jQuery組件的[''](http://livedemo.exadel.com/richfaces-demo/richfaces/modalPanel.jsf),不需要重新發明輪子(甚至更容易保持)。 –

回答

1

<a4j:support>操作完成時,您正在重新呈現整個表單。這樣,表單的HTML DOM樹就會被丟棄,並被來自ajax響應的樹所取代。這幾乎與<a4j:commandButton>需要執行的默認操作同時發生。這裏有一種競爭條件。如果發生在之前,默認動作將被執行,那麼它將永遠不會被執行,因爲源已經完全消失。

具體的功能要求並不完全清楚,因爲startProcessingMainAction()在給定的例子中沒有意義,它似乎是完全多餘的。但我認爲你可以通過將reRender屬性從<a4j:support>移動到<a4j:commandButton>來解決它,以便在默認操作完成時才重新呈現它。或者更好的是,完全刪除那個<a4j:support>,你似乎根本不需要它。

+0

感謝您的回答BalusC。我明白我的錯誤。 'a4j:support'和'startProcessingMainAction'這裏只是爲GUI提供服務,它允許用另一個內容替換確認問題來監視操作流(如進度條)。 這必須在行動開始之前或開始之前完成。如果你看到另一種方式來做到這一點,那將會很棒。 如果我將'reRender'從'a4j:support'移動到'a4j:commandButton',這將只在AFTER動作完成後重新渲染,否? – ollOne

+0

然後,您應該僅重新渲染進度條,而不是包括按鈕在內的整個表單。 – BalusC

+0

是的,我會嘗試個性化重新渲染,也許讓'a4j:poll'隱藏我的確認問題後顯示進度欄並啓用投票。我現在嘗試。 – ollOne