Оказание другой формы с помощью ajax заставляет его состояние представления потеряться, как мне добавить это обратно?
У меня
<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);
но я буду в худшем случае.
Ответы
Ответ 1
Это известная проблема в автоматической включенной библиотеке 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
.
См. также:
Ответ 2
Обходной путь для этого:
Сначала вам нужно установить обработчик 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("<input type='hidden' name='javax.faces.ViewState' />").val(viewState);
form.append(input);
});
}
</h:outputScript>