JSF: ui:include и (неработающая) область просмотра

У меня есть страница JSF с некоторыми общими элементами, а затем 4 части, которые динамически загружаются и включаются на основе различных действий пользователя. У меня есть bean-компоненты, которые инкапсулируют функциональность различных включений, и структура выглядит примерно так:

mainview.xhtml 
     --backed by--> mainViewBean (request scope) 
       --with managed property--> mainViewView (view scope)

include1.xhtml
     --backed by--> include1Bean (request scope)
       --with managed property--> mainViewBean

include2.xhtml
     --backed by--> include2Bean (request scope)
       --with managed property--> mainViewBean

include3.xhtml
     --backed by (and with component bindings to)--> include3Bean (request scope)
       --with managed property--> mainViewBean

include4.xhtml
     --backed by--> mainViewBean

На главной странице просмотра каждое включение включается через серию условно визуализированных h: panelGroups, как описано BalusC в следующих вопросах:

/questions/46425528/kakuyu-oblast-ispolzovat-v-shablone-jsf-20-for-wizard/46425537#46425537

/questions/15059916/kak-ajax-obnovit-dinamicheskoe-vklyuchenie-kontenta-po-menyu-navigatsii-jsf-spa/15059925#15059925

Bean-объект области видимости содержит некоторую различную информацию о представлении, касающуюся текущего состояния действий пользователя, элементов, которые он просматривает в настоящее время, и так далее.

Каждое из представленных представлений выполняет различные задачи с помощью сообщений ajax и non ajax. Моя проблема заключается в том, что определенные действия в определенных панелях, по-видимому, приводят к разрушению области видимости, и, похоже, для этого нет ни рифмы, ни причины. Я заранее прошу прощения за запутанный рабочий процесс, описанный ниже, но постараюсь быть максимально ясным.

Если я выполняю действия ajax в include3.xhtml, они отображают компоненты только внутри include, и я могу выполнять их весь день, и область просмотра остается. Если я выполню посты без Ajax, обновление обновит (и, возможно, добавит ранее не отрендеренный) include4.xhtml. Затем я могу впоследствии выполнить действие в любом из других включений.

Если я выполняю действие ajax в include1.xhtml, которое вызывает методы только в своем собственном компоненте поддержки и обновляет только свои собственные компоненты, область просмотра остается. Если я выполню действие ajax, которое вызывает метод в include3Bean и обновит div, содержащий include2.xhtml и include3.xhtml, область просмотра останется, и пока я продолжу выполнять действия в include1.xhtml, область просмотра останется. Как только я пытаюсь выполнить другое действие в одном из других включений, область просмотра уничтожается.

Как этот момент, я подумал про себя, что проблема должна быть в том, что я обновляю разные включения, кроме того, из которого вызывается действие. Но это не является проблемой (или, по крайней мере, единственной проблемой), как я сейчас объясню.

include2.xhtml имеет действие ajax, которое при запуске вызывает метод в mainViewBacking и обновляет div, содержащий include2.xhtml и include3.xhtml. Если я продолжу выполнять это действие или предприму любое другое действие в include2.xhtml (в том числе не в AJAX-действиях), все будет работать так, как ожидается, и область просмотра останется. Однако, если я впоследствии выполню действие в include3.xhtml, область просмотра будет уничтожена. Странно, что я могу выполнять действия в include1.xhtml, и они будут продолжать иметь доступ к области просмотра столько, сколько я хочу, но если я попытаюсь вернуться и выполнить действие в include2.xhtml или include3. xhtml, область просмотра снова теряется.

Я немного застрял на этом этапе, и я даже не уверен, как понять, что не так. Я предполагаю, что что-то в обновлении (и удалении или добавлении) включений приводит к потере области видимости, но из ранее связанных вопросов, похоже, это не должно быть проблемой, так как фактические значения src для пользовательского интерфейса Включения не генерируются динамически. И у меня есть частичное сохранение состояния для mainview.xhtml выключен.

Есть ли что-то в этих динамически отображаемых интерфейсах: включает в себя, что нарушает область видимости?

1 ответ

Решение

Изменить 2014-02-28:

Глядя на последнюю витрину omnifaces, я заметил, что BalusC реализовал скрипт, который должен решить эту же проблему и, вероятно, сделать это гораздо лучше, чем мой код ниже.

http://showcase.omnifaces.org/scripts/FixViewState

Оригинальный ответ:

Оказывается, это была ошибка в JSF, как описано BalusC здесь: http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html

К сожалению, его решение почему-то не сработало для меня. В результате я написал свою собственную (немного более раздражающую) работу, которую я предоставлю здесь другим, если им это понадобится.

Я добавил следующий javascript на страницу mainview.xhtml:

var lastForm = null;

        function getViewStateFromLastForm(callingElement){

            var currentForm = $(callingElement).closest("form");
            var formId = currentForm.attr("id");

            if(lastForm != null ){
                var viewState = $("#" + lastForm).children("[name='javax.faces.ViewState']").val();
                currentForm.children("[name='javax.faces.ViewState']").remove();

                $('<input/>').attr({
                    type: 'hidden',
                    id: 'javax.faces.ViewState',
                    name: 'javax.faces.ViewState',
                    autocomplete: 'off',
                    value: viewState
                }).appendTo(currentForm);
            }
            lastForm = formId;

        }

Тогда каждая кнопка на различных включенных страницах, которые отправляются на сервер, имеет вызов getViewStateFromLastForm(this); в их атрибутах onclick.

Другие вопросы по тегам