Веб-приложение, которое я разрабатываю с помощью MyFaces 2.0.3/PrimeFaces 2.2RC2, разделяется на содержимое и область навигации. В области навигации, которая включена в несколько страниц с использованием шаблонов (т. Е. <ui:define>
), есть некоторые виджеты (например, дерево навигации, разборные панели и т. Д.), Из которых я хочу сохранить состояние компонента по представлениям.JSF 2.0: Сохранение состояния компонента по нескольким точкам
Например, допустим, что я на главной странице. Когда я перейти к странице сведений о продукции, нажав на продукте в дереве навигации, мой Java-код вызывает редирект с помощью
navigationHandler.handleNavigation(context, null,
"/detailspage.jsf?faces-redirect=true")
Другим способом добраться до, что деталей страницы будет непосредственно нажав на тизер продукта, который отображается на главной странице. Соответствующий <h:link>
приведет нас к странице сведений.
В обоих случаях состояние расширения моего дерева навигации (компонента дерева PrimeFaces) и моих разборных панелей теряется. Я понимаю это потому, что перенаправление/h:link
приводит к созданию нового представления.
Каков наилучший способ борьбы с этим? Я уже использую MyFaces Orchestra в своем проекте вместе с его областью разговора, но я не уверен, что здесь какая-либо помощь (так как мне пришлось бы связать состояние виджета с расширением/свертыванием с бэк-файлом ... но, насколько я знаю, это невозможно). Есть ли способ рассказать JSF, какие компоненты состояний распространяются на следующее представление, предполагая, что тот же компонент существует в этом представлении?
Возможно, мне понадобится указатель в правильном направлении. Благодаря!
Update 1: Я просто попытался связывание панели и дерева на контексте сеанса боба, но это, кажется, не имеет никакого эффекта. Кроме того, я думаю, мне придется привязывать все дочерние компоненты (если есть) вручную, так что это не похоже на путь.
Обновление 2: Связывание компонентов пользовательского интерфейса с компонентами, не предназначенными для запроса, не является хорошей идеей (см. Ссылку, опубликованную в комментарии ниже). Если нет более простого подхода, я мог бы поступить следующий образом:
- Когда панель свернута или дерево расширяются, сохранить текущее состояние в контексте сеанса резервного боба (= сам компонент пользовательского интерфейса!)
- Состояние компонентов хранится на карте. Ключ карты является уникальным относительным идентификатором компонента (надеюсь). Я не могу использовать весь путь абсолютного компонента здесь, так как идентификаторы родительских контейнеров именования могут измениться, если представление изменится, предполагая, что эти идентификаторы генерируются программно.
- Как только будет создан новый вид, извлеките состояния компонентов из карты и примените их к компонентам. Например, в случае панелей я могу установить атрибут
collapsed
на значение, полученное из моего компонента, поддерживающего сессию.
Обновление 3: Я получил его, как описано выше. Чтобы подвести итог, решение состоит в том, чтобы сохранить соответствующие свойства в компоненте, зависящем от сеанса, вместо того, чтобы весь охват сеанса UIComponent. Затем, когда компонент будет реконструирован после того, как произошла навигация, установите значения атрибута, извлекая сохраненные свойства (используя EL), например.
<p:panel collapsed="#{backingBean.collapsedState}" ... />
(Это упрощенный пример. Так как я использую несколько панелей, я использую карту, чтобы хранить эти свойства, как описано выше).
Привязка компонентов пользовательского интерфейса к компоненту, включенному в сеанс, делает ** NOT ** работать. Это приводит к ошибке IllegalStateException, как только я обновляю страницу: «Компонент ID j_idt12: j_idt13: j_idt14 уже был найден в представлении.» _Correction: _ Я только что проверил это снова с автономной панелью и теперь это работает. Теперь давайте выясним, почему это не работает с моими другими панелями ... – tlind
Хорошо, поэтому связывание компонентов с фасолью с сессионным контуром, по-видимому, не-go. См. Http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=2479&start=0#p11946 и http://myfaces.apache.org/orchestra/myfaces-orchestra-core/component-bindings .html: «Чтобы избежать несоответствия жизненного цикла между компонентами и компонентами, любой компонент, который хранит привязку к компоненту, должен иметь область запроса». – tlind
Получил его работу, сохранив только соответствующие свойства в компоненте, зависящем от сеанса (вместо того, чтобы сделать весь охват сеанса UIComponent). См. Мои обновления выше. – tlind