2

在 JSF 2.1 wep 应用程序中,我有一列包含命令按钮的数据表。commandButton 触发的动作可能会引发错误。如果没有抛出错误,我想打开一个对话框,或者在另一种情况下打开一个包含错误消息的框

JSF

<h:form>
    <p:dataTable var="foo" value="#{myBean.foos}" >
        <p:column>#{foo.id}</p:column>
        <p:column>
            <p:commandButton title="Action" action="#{myBean.action()}" onComplete="handleResult(xhr, status, args)" >
                <f:setPropertyActionListener value="#{foo}" target="#{myBean.selectedFoo}" />
            </p:commandButton>
        </p:column>
    </p:dataTable>
</h:form>

JavaScript

function handleRequest(xhr, status, args) {
    if (!args.success) {
        displayBox(args.errorMsg);
    } else {
        displayDialog();
    }
}

豆豆

@ManagedBean
@ViewScoped
public class MyBean {
    private List<Foo> foos;
    private Foo selectedFoo;

    public void action() {
        try {
            // business logic
        } catch (Exception ex) {
            RequestContext rContext = RequestContext.getCurrentInstance();
            rContext.addCallbackParam("success", false);
            rContext.addCallbackParam("errorMsg", ex.getMessage());
        }
    }
}

我能想到的唯一解决方案是使用 PrimeFacesRequestContext.callBackParam()并编写一个 JS 函数来读取它并决定打开什么。

有没有更流畅的方法?如果可能的话,我会考虑利用验证的概念,但我找不到如何在 JS 中拦截错误的示例。

4

1 回答 1

2

规范的方法是只添加一个全局面孔消息(因此,带有null客户端 ID)。

public void action() {
    try {
        // business logic
    } catch (Exception ex) {
        context.validationFailed();
        context.addMessage(null, new FacesMessage(
            FacesMessage.SEVERITY_ERROR, ex.getMessage(), null));
    }
}

(调用FacesContext#validationFailed()将导致#{facesContext.validationFailed}在 EL 中进行评估true;这通常在 的情况下设置ValidatorException

然后,要显示一个仅用于全局消息的框,只需使用<p:messages globalOnly="true">.

<p:messages globalOnly="true" autoUpdate="true" />

并显示一个关于成功结果的对话框,让它在执行成功 发时呈现:

<p:outputPanel autoUpdate="true">
    <p:dialog visible="true" rendered="#{facesContext.postback and not facesContext.validationFailed}">
        A successful postback is performed!
    </p:dialog>
</p:outputPanel>

如有必要autoUpdate="true",将一个或两个组件替换为 ,update="messagesId dialogPanelId"以便仅在按下特定按钮时触发。

于 2013-01-04T13:02:44.920 回答