3

JBoss 7.1 と Richfaces 4.1 で JSF Web アプリケーションを使用しています。web.xml でカスタム エラー ページを構成しようとしましたが、AJAX 要求では機能しないという問題に遭遇しました。解決策として、エラーページを正常に表示するOmnifaces FullAjaxExceptionHandlerを使用しようとしました。

ただし、ユーザーが追加情報を入力して、これを例外と共にメールとして送信できるフォームを追加したかったのです。問題は、エラー ページで送信ボタンが機能しないことです。それをクリックすると、エラーページがリロードされました。次のクリックでは、すべてが期待どおりに機能します。

エラー ページのテンプレートにある小さなメニューの h:commandlinks でも同じ問題が発生します。

私はJSFを初めて使用するので、なぜこれが起こるのか、どのように修正できるのかよくわかりません。または、これを達成するためのより良い方法はありますか?

4

1 に答える 1

1

これは、JSF仕様の問題790に関連しており、要約すると、1つ以上の<h:form>コンポーネントを含むコンポーネントを更新しても、それらのフォームの新しいビューステート識別子が適切に更新されません。

この問題は、今後のJSF 2.2で修正されますが、それまでは、次のJavaScriptベースの回避策を使用する必要があります。

jsf.ajax.addOnEvent(function(data) {
    if (data.status == "success") {
        var viewState = getViewState(data.responseXML);

        if (viewState) {
            for (var i = 0; i < document.forms.length; i++) {
                var form = document.forms[i];

                if (!hasViewState(form)) {
                    createViewState(form, viewState);
                }
            }
        }
    }
});

function getViewState(responseXML) {
    var updates = responseXML.getElementsByTagName("update");

    for (var i = 0; i < updates.length; i++) {
        var update = updates[i];

        if (update.getAttribute("id") == "javax.faces.ViewState") {
            return update.firstChild.nodeValue;
        }
    }

    return null;
}

function hasViewState(form) {
    for (var i = 0; i < form.elements.length; i++) {
        if (form.elements[i].name == "javax.faces.ViewState") {
            return true;
        }
    }

    return false;
}

function createViewState(form, viewState) {
    var hidden;

    try {
        hidden = document.createElement("<input name='javax.faces.ViewState'>"); // IE6-8.
    } catch(e) {
        hidden = document.createElement("input");
        hidden.setAttribute("name", "javax.faces.ViewState");
    }

    hidden.setAttribute("type", "hidden");
    hidden.setAttribute("value", viewState);
    hidden.setAttribute("autocomplete", "off");
    form.appendChild(hidden);
}

エラーページの<h:outputScript name="some.js" target="head">中に含めるだけです。<h:body>ページがJSFを使用していることを保証できない場合は、呼び出す前にチェック<f:ajax>を追加することをお勧めします。if (typeof jsf !== 'undefined')jsf.ajax.addOnEvent()

JSFコンポーネントライブラリPrimeFacesは、コアajaxエンジンでこの問題をすでに解決しているため、すでに使用している場合は、すべての<f:ajax>リンク/ボタンをPrimeFacesのものに置き換えることをお勧めします。

参照:

于 2012-11-12T14:53:42.387 に答える