Динамический пользовательский интерфейс: включить внутри пользовательского интерфейса: повторить. Есть ли простое решение?



Я хочу динамически выбрать facelet для отображения некоторого элемента в моем списке данных. Первая попытка будет:

<ui:repeat value="#{panels}" var="panel">
  <ui:include src="#{panel.facelet}">
</ui:repeat>

Но это не будет работать, так как src ui: include вычисляется слишком рано. Информация facelet действительно динамична, поэтому я не могу использовать c:forEach (не рекомендуется смешивать с facelets). Я думаю, что все это сводится к поиску пользовательского интерфейса на основе компонентов: include alternative.

Есть ли такая вещь, или мне нужно написать свою собственную?

150   3  

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, это может не сработать.

Могу ли я спросить, почему, б / к иногда с пониманием высокого уровня, поэтому гуру могут предложить гораздо более простые идеи для достижения той же цели

    Ничего не найдено.

Добавить ответ:
Отменить.