Динамический пользовательский интерфейс: включить внутри пользовательского интерфейса: повторить. Есть ли простое решение?
Я хочу динамически выбрать facelet для отображения некоторого элемента в моем списке данных. Первая попытка будет:
<ui:repeat value="#{panels}" var="panel">
<ui:include src="#{panel.facelet}">
</ui:repeat>
Но это не будет работать, так как src ui: include вычисляется слишком рано. Информация facelet действительно динамична, поэтому я не могу использовать c:forEach (не рекомендуется смешивать с facelets). Я думаю, что все это сводится к поиску пользовательского интерфейса на основе компонентов: include alternative.
Есть ли такая вещь, или мне нужно написать свою собственную?
3 ответов:
C: forEach решит эту задачу, почему вы не можете ее использовать?
Интересная статья по этому вопросу: http://www.ilikespam.com/blog/c:foreach-vs-ui:repeat-in-facelets
Я думаю, что нашел то относительно простое решение, которое вы искали.
Я тоже начал с ui: include внутри ui: repeat, как у вас, но я принял, что мне пришлось использовать c:forEach, и c:forEach отлично работал для динамического получения другого набора xhtml/компонентов, чтобы включать даже при взаимодействии с пользователем, изменяющем вещи в представлении, как я думаю, у вас есть. Это выглядело так:
<c:forEach var="thing" items="#{view.things}"> <ui:include src="#{thing.renderComponent}"> <ui:param name="thing" value="#{thing}"/> </ui:include> </c:forEach>Однако мой ui: param не работал - каждый компонент, который я включил была передана одна и та же"вещь" /объект, хотя мы успешно использовали разные вещи/объекты для динамического включения различных компонентов.
Именно тогда я нашел этот пост, который вдохновил меня обернуть мой ui:include в F:subview. И теперь все отлично работает со следующим кодом:
<c:forEach var="thing" items="#{view.things}" varStatus="loop"> <f:subview id="thing_#{loop.index}"> <ui:include src="#{thing.renderComponent}"> <ui:param name="thing" value="#{thing}"/> </ui:include> </f:subview> </c:forEach>
Я помню, как пытался сделать что-то подобное, используя пользовательский тег и FaceletHandler и т. д. В конце концов, все эти мелкие проблемы со временем рендеринга сделали его не стоящим усилий. Имейте в виду, что я был (и все еще остаюсь :-(...) Использование facelets для jsf 1.1, поэтому не уверен, что это лучше в более поздних версиях.
Насколько динамично / с каким количеством различных фасетов вам приходится иметь дело? Причина, по которой я спрашиваю, заключается в том, что вы можете (позаимствовать термин из мастеров компилятора) развернуть свой цикл. Вместо
<ui:repeat value="#{panels}" var="panel"> <ui:include src="#{panel.facelet}"> </ui:repeat>Вы могли бы сделать
<custom:panelOneFacelet rendered="#{hasPanel1}" /> <custom:panelTwoFacelet rendered="#{hasPanel2}" /> <!-- etc... -->И в вашем фейслете будет что-то вроде:
<c:if test="#rendered" > <!-- EVERYTHING IN THE FACELET HERE!!!--> </c:if>Такого рода низкие технологии подход хорош для небольшого контролируемого набора, но если у вас есть очень большой и изменяющийся набор facelets, это может не сработать.
Могу ли я спросить, почему, б / к иногда с пониманием высокого уровня, поэтому гуру могут предложить гораздо более простые идеи для достижения той же цели
Comments