Как использовать связывание компонентов в 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());
}