Есть много разных способов реализовать повторно используемый поисковый компонент в jsf, но я не могу решить, какой путь выбрать в моем приложении.Основными функциями являются поиск и отображение результатов, если найдено несколько предметов.Если мне нужно создать составной компонент или обычную лицевую панель с помощью ui: params, это мой вопрос.Я построил два доказательства концепций, которые будут объяснены в этом вопросе.
составной компонент
Я построил составной компонент для этого.Поисковая часть была проста, без проблем.Я определил следующий интерфейс и реализацию составного компонента.
<cc:interface componentType="farmSearchDialogComponent">
<cc:valueHolder name="farmId" />
<cc:valueHolder name="farmInfo" />
<cc:attribute name="id" />
<cc:attribute name="widgetVar" />
<cc:attribute name="update" />
</cc:interface>
<cc:implementation>
<p:dialog id="#{cc.attrs.id}" widgetVar="#{cc.attrs.widgetVar}" width="700" closable="false" modal="true" resizable="false">
<f:facet name="header">#{msg.farm_searchdialog}</f:facet>
<!--non relevant search input fields and button removed-->
<!-- result table if multiple elements found -->
<p:dataTable id="fR" value="#{cc.sr}" var="sr" binding="#{cc.dataTable}" >
<p:column width="32">
<!-- button to choose single result from result table -->
<p:commandButton id="sB" update="#{cc.attrs.update}" action="#{cc.selectFarm(sr)}" oncomplete="PF('#{cc.attrs.widgetVar}').hide()" />
</p:column>
</p:dataTable>
</p:dialog>
</cc:implementation>
Компонент поиска используется в xhtml, как показано в следующем коде.Важным параметром является farmInfo="#{AnimalBasics_v.animalFarm}"
.Это ссылка на атрибут контроллера, который устанавливается, если выбран результат поиска или был найден только один элемент.
<h:form>
<qc:farmSearchDialog id="fsdPuL" widgetVar="fsPuL" farmInfo="#{AnimalBasics_v.animalFarm}" update=":someForm" />
</h:form>
сводный составной компонент
Это сработало, как и ожидалось, за исключением того факта, что составные компоненты (должны быть?) не сохраняют состояния, и мне пришлось связать данные с binding="#{cc.dataTable}"
в результате обработки данных, чтобы заставить этот компонент работать так, как я хотел.
facelet и ui:include / ui: param
HTML-код формы поиска и диалоговое окно результатов выглядит очень похоже.Ну, нет <cc:interface>
и <cc:implementation>
, но есть одинаковые поля ввода для поиска и данные для отображения нескольких результатов поиска.
<h:form id="adrSF">
<c:set value="#{AddressSearchC_v}" var="cc" />
<!--non relevant search input fields -->
<p:commandButton action="#{cc.search(adrView)}" />
<p:dialog id="rDlgl" visible="#{not empty cc.sr}">
<!-- result table if multiple elements found -->
<p:dataTable id="asrDtl" value="#{cc.sr}" var="asr">
<p:column width="32">
<p:commandButton id="sB" actionListener="#{adrView[adrButtonAction](asr)}" action="#{cc.closeSearchResults()}" update="@form"/>
</p:column>
</p:dataTable>
</p:dialog>
</h:form>
Мне нужен был способ передать ссылку на контроллер AddressSearchC_v
поэтому я знаю, где установить результат поиска в контроллере поиска.Я использовал ui: param, чтобы передать их и использовать их с EL actionListener="#{adrView[adrButtonAction](asr)}"
, , объясненным здесь
. С помощью этого можно создать кнопку, которая устанавливает результат непосредственно в принимающем контроллере.Теперь, если я нахожу только 1 результат, мне нужно установить результат непосредственно в контроллере serach.Поэтому я передаю ссылку на получающее представление методу поиска <p:commandButton action="#{cc.search(adrView)}" />
.Я определил интерфейс с классом результатов поиска как param, который реализуется принимающим контроллером.При этом я могу привести ссылку на получающее представление в контроллере поиска к определенному интерфейсу и вызвать метод для установки результата поиска.
Форма поиска включена, как показано ниже.
<ui:include src="/components/search/addressSearchComp.xhtml">
<ui:param name="adrView" value="#{CRMBasics_v}" />
<ui:param name="adrButtonAction" value="setAddressFromSearch" />
</ui:include>
суммарный фейслет и пользовательский интерфейс: include / ui: param
Используя эту попытку, мне приходится делать два разных способа установки результата поиска для обработки получающим контроллером, но это работает также без необходимости что-либо менятьна компонентах поиска, и я могу использовать его везде, где захочу.
Мой вывод
По моему мнению, составной компонент более элегантен, но тот факт, что составные компоненты разработаны так, что они не имеют состоянияможет быть ограничением в будущем.Я надеюсь, что кто-то может помочь мне разделить эти два подхода и рассказать мне о плюсах и минусах, которые я, возможно, пропустил, и, возможно, у меня есть несколько советов передовой практики для меня.Или, может быть, есть другой, более элегантный способ решить эту проблему?
Спасибо, что поделились своим опытом.