我正在使用 JSF 1.2 和 RichFaces 3.3.3 。我在使用Twitter Bootstrap设计的页面上工作。我需要对这样的订单处理一个动作:
所以我需要在同一时间做两件事,交替对话框内容并在页面bean中启动一个动作。今天,我能够改变对话框内容,但是不会处理在我的bean中启动的动作...... 要做到这一点,我在我的bean中使用一个标志来切换对话框内容,由a4j:support onclick(在正常调用之前执行)修改,执行动作的a4j:commandButton。
<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:支持效果很好),但由于未调用a4j:commandButton操作,其oncomplete将立即执行,对话框消失。
我希望你能帮助我,这是我用户界面的一个重要部分,截止日期是在本周末^ _ ^
更新我观察到随机行为。很少(现在是2次),但有时,一切正常,99%命令按钮的动作没有被调用:/
答案 0 :(得分:1)
<a4j:support>
操作完成后,您将重新呈现整个表单。这样,表单的HTML DOM树将被删除并替换为ajax响应中的一个。这几乎与需要执行<a4j:commandButton>
的默认操作的同时发生。这里有竞争条件。如果在之前发生默认操作将被执行,那么它将永远不会被执行,因为源已完全消失。
具体的功能要求并不完全清楚,因为startProcessingMainAction()
在给定的例子中没有意义,它似乎完全是多余的。但我认为您可以通过将reRender
属性从<a4j:support>
移动到<a4j:commandButton>
来解决此问题,以便仅在默认操作完成时重新呈现它。或者甚至更好,只需完全删除<a4j:support>
,您根本不需要它。