Как правильно использовать привязку компонентов в JSF? (компонент с охватом запросов в сеансе связи bean)
Мохара 2.1.21
Я обновил свой вопрос на основе комментариев. У меня две ситуации, когда компонент связан с сеансом сервера bean. (Дополнительные ссылки с информацией: Атрибут связывания вызывает дублирование идентификатора компонента, найденного в представлении и qaru.site/info/8734/...)
Версия 1:
single.xhtml:
<h:outputText value=... binding="#{mysessionbean.out}" />
Java:
@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" />
Java:
@SessionScoped @Named public class Mysessionbean {
UIOutput out;
//getter and setter ....
}
Версия 1 в порядке. (По крайней мере, до сих пор я не встречал никаких ошибок). Но в версии 2 ошибка дубликата id возникает, если я перемещаюсь с одной страницы на другую. Почему это происходит?
Безопасно ли использовать компонент (с запросом) (в версии 1) с привязкой к сеансу?
Существуют ли другие варианты использования?
Изменить:
Функциональное требование 1:
Я хочу использовать Primefaces datatable в представлении. Мне нужна информация из этого datatable. (Например, выбранный индекс строки или строки). Поэтому привязка данных datatable помогает мне получить эту информацию.
Функциональное требование 2:
Связывание компонентов в составных компонентах. Они будут привязаны к сеансу bean. (И используется в основном на одной странице, но что, если я использовал его на другой странице?
Требования 3
Ситуация, как в "Версии 2". Шаблон с меню перфолей и привязкой к сеансу. Для этого я использовал EL-Binding.
Ответы
Ответ 1
В JSF 2.x, если вы не хотите манипулировать компонентами программно (что само по себе также довольно подозрительно), нет разумного реального случая использования в мире для привязки компонентов к поддержке bean. Разумеется, если они не будут использоваться в самой базе bean, или если это только их атрибуты, которые были сплющены.
Что касается функционального требования для получения текущей строки таблицы данных, здесь перечислены намного лучшие способы, Как передать выбранную строку команде 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}" />
с помощью bean
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}" ... />
и экземпляр далее нигде не использовался в bean, а затем просто избавиться от ненужного свойства:
<h:inputText ... required="#{not empty param[save.clientId]}" />
...
<h:commandButton binding="#{save}" ... />
Если по какой-то неясной причине действительно нет способа, то разделите все свойства с областью охвата области охвата bean на отдельный запрос с охватом bean, который вы в свою очередь связываете с формами действий. Область сеанса может быть просто введена как @ManagedProperty
области с запросом.
См. также:
Ответ 2
Мы столкнулись с подобной проблемой, и я просто хочу поделиться нашим решением:
Проблема:
По мнению, существует (расширенная в основном настраиваемая) дата.
<x:dataTable binding="#{bean.someSomeDataTable}" />
После перехода на другую страницу и обратно мы хотели, чтобы у datatable было то же самое состояние. Раньше мы решили, что привязывание данных к поддержке bean. Это отлично работает с JSP. С Facelets мы не могли этого сделать (повторяющиеся ошибки ID). Таким образом, мы использовали привязку, но только сохранили/восстановили состояние компонента datatable.
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());
}