2012-06-27 91 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