JSF 2.0: Сохранение состояния компонента на нескольких видах
Вопрос
Веб-приложение, которое я использую, используя MyFaces 2.0.3 / Primefaces 2.2RC2, разделен на содержание и область навигации. В области навигации, которая включена на несколько страниц с использованием шаблонов (т.е. <ui:define>
) Есть несколько виджетов (например, навигационное дерево, разборные панели и т. Д.) О чем я хочу сохранить состояние компонента по всем видам.
Например, скажем, я на домашней странице. Когда я ориентирую на страницу сведения о продукте, нажав на продукт в дереве навигации, мой код Java запускает перенаправить, используя
navigationHandler.handleNavigation(context, null,
"/detailspage.jsf?faces-redirect=true")
Еще один способ попадания на эту страницу деталей будет непосредственно нажатывать на продуктный тизер, который отображается на домашней странице. Соответствующее <h:link>
приведет нас к странице сведений.
В обоих случаях состояние расширения моего дерева навигации (компонент древесного дерева) и мои разборные панели теряются. Я понимаю, что это потому, что перенаправить / h:link
приводит к созданию нового мнения.
Какой лучший способ иметь дело с этим? Я уже использую MyFaces Orchestra в моем проекте вместе со своей разговорами, но я не уверен, что это какая-либо помощь здесь (поскольку мне придется связать расширение / рухнутое состояние виджетов в боб. Но насколько я знаю, это невозможно). Есть ли способ сказать JSF, какие компонентные состояния распространяются на следующий вид, предполагая, что тот же компонент существует в этом представлении?
Я думаю, мне понадобится указатель в правильное направление здесь. Спасибо!
Обновление 1: Я только что попытался привязать панели и дерево на сессию-населенный боб, но это, кажется, не влияет. Кроме того, я думаю, мне придется связывать все детские компоненты (если есть) вручную, так что это не похоже на пути.
Обновление 2: Компоненты подключения пользовательских интерфейсов к не запрашиванию Scoped Beans не очень хорошая идея (см. Ссылка, которую я разместил в комментарии ниже). Если нет более простых подходов, я мог бы придеться следующим образом:
- Когда панель рухнула или дерево расширяется, сохраните текущее состояние в бобовом компонентах, находящихся в сессии (! = Сам компонент пользовательского интерфейса)
- Состояния компонентов хранятся на карте. Ключ карты является компонентным (надеюсь) уникальным, относительным идентификатором. Я не могу использовать весь абсолютный компонентный путь здесь, поскольку идентификаторы контейнеров родительских имен могут измениться, если изменения в представлении, при условии, что эти идентификаторы генерируются программно.
- Как только появится новый взгляд, извлеките состояния компонентов с карты и примените их к компонентам. Например, в случае панелей я могу установить
collapsed
Атрибут значения, полученному из моего сеанса, находящегося на уровне бона.
Обновление 3: Я получил его, работая как описано выше. Суммируйте его, решение состоит в том, чтобы хранить соответствующие свойства в сессионном бобере вместо того, чтобы сделать весь навес на уровне UIComponent. Затем, когда компонент повторно сконструирован после навигации, установите значения атрибута путем извлечения сохраненных свойств (используя EL), например,
<p:panel collapsed="#{backingBean.collapsedState}" ... />
(Это упрощенный пример. Поскольку я использую несколько панелей, я использую карту для хранения этих свойств, как описано выше).
Решение
Одним из решений будет использование сеансопированных бобов.
Другие советы
Что вы имеете в виду под разборными панелями? Я спрашиваю, потому что есть компонент, который является скрепленным, а также компонентом. Я использую на панели навигации в моем проекте. У AccordianPanel есть атрибут, названный «ActiveIndex». Вот что я сделал в моей сессии, чтобы поддерживать состояние моих аккордеонных вкладок:
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>
Я не использую компонент дерева для навигации, как это представил мой проект с некоторыми трудностями, которые были легко преодолены, используя аккордеографию, поэтому я не могу говорить с этой частью вашей навигации.