我正在使用JSF 1.2和RichFaces 3.3.3。我在使用 Twitter Bootstrap 设计的页面上工作。我需要处理这样的订单操作:
- 用户点击页面上的操作按钮,
- 一个模态对话框打开并要求用户确认操作(如果用户取消操作,过程当然在这里结束),
- 在确认的情况下,对话框的内容从确认文本更改为其他一些内容以遵循操作处理(在某些情况下显示进度条,例如,在代码中只是一个等待文本),
- 操作完成后,对话框消失。
所以我需要同时做两件事,交替对话内容并在页面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 的操作:/