2011-01-05 4 views
1

Веб-приложение, которое я разрабатываю с помощью 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}" ... /> 

(Это упрощенный пример. Так как я использую несколько панелей, я использую карту, чтобы хранить эти свойства, как описано выше).

ответ

0

Одним из решений было бы использовать фасоль с сессией.

+0

Привязка компонентов пользовательского интерфейса к компоненту, включенному в сеанс, делает ** NOT ** работать. Это приводит к ошибке IllegalStateException, как только я обновляю страницу: «Компонент ID j_idt12: j_idt13: j_idt14 уже был найден в представлении.» _Correction: _ Я только что проверил это снова с автономной панелью и теперь это работает. Теперь давайте выясним, почему это не работает с моими другими панелями ... – tlind

+0

Хорошо, поэтому связывание компонентов с фасолью с сессионным контуром, по-видимому, не-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

+0

Получил его работу, сохранив только соответствующие свойства в компоненте, зависящем от сеанса (вместо того, чтобы сделать весь охват сеанса UIComponent). См. Мои обновления выше. – tlind

0

Что вы имеете в виду под складными панелями? Я спрашиваю, есть ли компонент, который может быть закрыт, а также компонент. Я использую в навигационной панели в своем проекте. СогласиеPanel имеет атрибут с именем «activeIndex». Вот что я сделал в моем SessionBean поддерживать состояние моих закладок аккордеона:

private int tabIndex; //declared a private variable 

    public SessionBean() { 
     tabIndex = 100; //set the initial tab index to 100 so all tabs are closed when page loads. 
    } 

    public int getTabIndex(){ 
     return tabIndex; 
    } 

    public void setTabIndex(int tabIndex){ 
     this.tabIndex=tabIndex; 
    } 

in my navigation pane: 



<p:accordionPanel activeIndex="#{sessionBean.tabIndex}" collapsible="true" autoHeight="false"> 
    <p:tab title="#{tab1_title}"> 
     <h:commandLink value="link here" action="target_page?faces-redirect=true" /><br/> 
    </p:tab> 
    <p:tab title="#{tab2_title}"> 
     <h:commandLink value="link here" action="target_page?faces-redirect=true" /> 
    </p:tab> 
    <p:tab title="#{tab3_title}"> 
     <h:commandLink value="link here" action="target_page?faces-redirect=true" /> 
    </p:tab> 
</p:accordionPanel> 

Я не использую компонент дерева для навигации, который представил свой проект с некоторыми трудностями, которые были легко преодолены с помощью accordionPanel, поэтому я не могу говорить с этой частью вашей навигации.

+0

С «разборными панелями» я имел в виду обычные '' экземпляры. Таким образом, мое решение для панелей аналогично вашему, а именно, извлечение значения «спящего» из бэк-компонента, зависящего от сеанса: ' tlind

+0

Для дерева подход подобен; здесь вместо прослушивателя переключателей вам нужно выбрать, развернуть и свернуть прослушиватели, чтобы поддерживать состояние на стороне сервера. В этих слушателях просто обновляйте узлы дерева (например, 'treeNode.setExpanded (true)') для распространения состояния клиента на сервер. В следующий раз, когда дерево будет перестроено при перезагрузке страницы, эти значения в узлах дерева будут использоваться для инициализации нового дерева. Тем не менее, я должен отметить, что в PrimeFaces 2.2RC2 слушатели с расширением и свертыванием, похоже, сломаны. – tlind

+0

Я буду помнить об этом, поскольку мы предпочли бы использовать дерево в нашей навигационной системе. Спасибо за совет. – Sean

Смежные вопросы