Как использовать связывание компонентов в JSF правильно? (компонент в области запроса в компоненте, определяемом сессией)

Мохара 2.1.21

Я обновил свой вопрос на основе комментариев. У меня есть две ситуации, когда компонент связан с компонентом сеанса сервера. (Дополнительные ссылки с информацией: атрибут Binding приводит к дублированию идентификатора компонента, найденного в представлении и /questions/19171223/chto-takoe-privyazka-komponentov-v-jsf-kogda-eto-predpochtitelno-ispolzovat/19171227#19171227)

Версия 1:

single.xhtml:

 <h:outputText value=... binding="#{mysessionbean.out}" />

Джава:

 @SessionScoped @Named public class Mysessionbean {
    UIOutput out;
    //getter and setter ....
 }

Версия 2:

template.xhtml:

 <h:outputText value=... binding="#{mysessionbean.out}"

view1.xhtml:

 <ui:composition template="template.xhtml" />

view2.xhtml:

 <ui:composition template="template.xhtml" />

Джава:

 @SessionScoped @Named public class Mysessionbean {
    UIOutput out;
    //getter and setter ....
 }

Версия 1 в порядке. (По крайней мере, я пока не встречал ошибок). Но в версии 2 возникает ошибка дублирования идентификатора, если я перехожу с одной страницы на другую. Почему это происходит? Безопасно ли использовать (в рамках запроса) компонент (в версии 1) с привязкой в ​​рамках сеанса? Есть ли другие варианты использования для рассмотрения?

Изменить:Функциональное требование 1:

Я хочу использовать Primefaces datatable в представлении. Мне нужна информация из этого источника данных. (Например, выбранная строка или индекс строки). Поэтому привязка данных помогает мне получить эту информацию.

Функциональное требование 2:

Связывание компонентов в составных компонентах. Они будут связаны с сессионной областью действия. (И используется в основном на одной странице, но что, если я использовал его на другой странице?

Требования 3

Ситуация как в "Версии 2". Шаблон с меню простых лиц и привязкой к сессии. Для этого я использовал EL-Binding.

2 ответа

Решение

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


Что касается функциональных требований для получения текущей строки таблицы данных, здесь перечислены намного лучшие способы. Как я могу передать выбранную строку в commandLink внутри dataTable? Например, если ваша среда поддерживает EL 2.2:

<h:dataTable value="#{bean.items}" var="item">
    <h:column>
        <h:commandLink value="Foo" action="#{bean.foo(item)}" />

Два последних требования совершенно неясны. По крайней мере, если вы делаете что-то вроде:

<x:someComponent binding="#{bean.someComponent}" />

с в бобе

someComponent.setSomeAttribute(someAttribute);
someComponent.setOtherAttribute(otherAttribute);

тогда вы должны вместо этого делать

<x:someComponent someAttribute="#{bean.someAttribute}" otherAttribute="#{bean.otherAttribute}" />

Или, если вы намереваетесь использовать компонент где-то еще в представлении, например, так

<h:inputText ... required="#{not empty param[bean.save.clientId]}" />
...
<h:commandButton binding="#{bean.save}" ... />

и экземпляр далее нигде не использовался в бобе, а затем просто полностью избавился от ненужного свойства:

<h:inputText ... required="#{not empty param[save.clientId]}" />
...
<h:commandButton binding="#{save}" ... />

Если по какой-то непонятной причине действительно нет никакого способа, то разделите все свойства области запроса для объекта сессионной области на отдельный компонент с областью запроса, который вы, в свою очередь, связываете с действиями формы. Сеанс области можно просто ввести как @ManagedProperty запроса, охватываемого одним.


Смотрите также:

Мы столкнулись с похожей проблемой, и я просто хочу поделиться нашим решением:

Проблема: в представлении была (расширенная, в значительной степени настроенная) информация.

<x:dataTable binding="#{bean.someSomeDataTable}" />

После перехода на другую страницу и обратно мы хотели, чтобы данные имели точно такое же состояние. Ранее мы решили это путем привязки данных к бобам. Это работало нормально с JSP. С Facelets мы не могли этого сделать (ошибки Duplicate ID). Поэтому мы использовали привязку, но только сохранили / восстановили состояние компонента с данными.

public HtmlDataTable getSomeDataTable()
{
 HtmlDataTable htmlDataTable = new HtmlDataTable();
 if (tableState != null)
   htmlDataTable.restoreState(FacesContext.getCurrentInstance(), tableState);
 return htmlDataTable;
}

public void setSomeDataTable(HtmlDataTable table)
{
  tableState = table.saveState(FacesContext.getCurrentInstance());
}
Другие вопросы по тегам