Рендеринг другой формы с помощью ajax приводит к потере состояния просмотра, как мне добавить это обратно? - PullRequest
13 голосов
/ 18 октября 2011

у меня

<h:form>
    <h:commandLink action="#{my_fake_ajax_link}">
        <h:outputText value="Link" />
        <f:ajax render=":mydiv" />
    </h:commandLink>
</h:form>

<h:panelGroup layout="block" id="mydiv">
    <h:form>
        <h:commandLink action="#{mybean.delete(0)}">
            <h:outputText value="Here" />
            <f:ajax render="@form" />
        </h:commandLink>
    </h:form>
</h:panelGroup>

Когда я нажимаю один раз на ссылку "my_fake_ajax_link", мне приходится дважды щелкать ссылку "удалить". Это только пример. У меня нет этого реального случая. У меня есть несколько форм на странице, и я не могу просто добавить их все в одной форме.

Я проверил, в чем проблема, и это:

  • Когда вы нажимаете "my_fake_ajax_link", mydiv обновляется с помощью ajax, как и должно быть.
  • Отсутствует ViewState обновленной формы на ajax.

Как я могу добавить ViewState? Как я могу заставить его работать без использования только одной формы? Это похоже на ошибку JSF для меня. Я не хочу обновлять этот div автоматически с помощью

jQuery("#mydiv").load(document.location.href);

но я сделаю это в худшем случае.

Ответы [ 2 ]

22 голосов
/ 18 октября 2011

Это известная проблема в автоматически включенной библиотеке jsf.js JSF, которая обрабатывает ответы ajax. См. Также Выпуск спецификации JSF 790 , который исправлен в готовящейся JSF 2.3. Между тем, в JSF 2.0 / 2.1 / 2.2 вам необходимо явно указать идентификатор другого <h:form> внутри атрибута render, чтобы инициировать правильное добавление состояния просмотра.

<h:form>
    <h:commandLink action="#{my_fake_ajax_link}">
        <h:outputText value="Link" />
        <f:ajax render=":mydiv :mydivForm" />
    </h:commandLink>
</h:form>

<h:panelGroup layout="block" id="mydiv">
    <h:form id="mydivForm">
        <h:commandLink action="#{mybean.delete(0)}">
            <h:outputText value="Here" />
            <f:ajax render="@form" />
        </h:commandLink>
    </h:form>
</h:panelGroup>

Нет, это не приводит к дублированию служебной информации или разметке в ответе ajax. Либо используйте OmniFaces fixviewstate.js.

Смотри также:

0 голосов
/ 09 декабря 2013

Обходной путь для этого:

Сначала вам нужно установить обработчик onevent для кнопки, которая отправляет запрос ajax:

<h:form id="newComment">
    <h:commandButton id="saveNewComment" action="#{postBean.actionSaveNewCommentAjax}" value="#{rb['speichern']}">
        <f:ajax execute="@form" render=":commentsBox" onevent="function(data) { fixOtherFormsViewState(data, 'newComment') }" />
    </h:commandButton>
</h:form>

Затем вам нужно объявить методы javascript, которыепримет правильное значение viewState и добавит его ко всем формам, у которых его нет:

<h:outputScript>
function fixOtherFormsViewState(data, goodFormId) {
    if (data.status != "success") {
        return;
    }

    var viewState = jQuery("#" + goodFormId + " input[name='javax.faces.ViewState']").val();
    jQuery("form:not(:contains(input[name='javax.faces.ViewState']))").each(function (idx, elem) {
        var form = jQuery(elem);
        var input = jQuery("&lt;input type='hidden' name='javax.faces.ViewState' /&gt;").val(viewState);
        form.append(input);
    });
}
</h:outputScript>
...