Dynamic ui:include inside ui:repeat. Is there a simple solution?

余生颓废 提交于 2019-12-09 18:05:09

问题


I want to dynamically pick a facelet to render some item in my data list. The first try would be:

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

But it won't work since src of ui:include is evaluated too early. The facelet information is truly dynamic, so I cannot use c:forEach (not really recommended to mix with facelets either). I guess it all boils down to finding a component based ui:include alternative.

Is there such thing or I need to write my own?


回答1:


c:forEach will solve it, why can't you use it?

Interesting article regarding that issue: http://www.ilikespam.com/blog/c:foreach-vs-ui:repeat-in-facelets




回答2:


I think I've found that relatively simple solution you've been looking for.

I too started with a ui:include inside a ui:repeat like yours, but I accepted that I had to use a c:forEach, and the c:forEach worked great for dynamically getting a different set of xhtml/components to include even with user interaction changing things in the View like I think you have. It looked like this:

<c:forEach var="thing" items="#{view.things}">
        <ui:include src="#{thing.renderComponent}">
            <ui:param name="thing" value="#{thing}"/>
        </ui:include>
</c:forEach>

However, my ui:param wasn't working - every component I included was passed the same "thing"/Object even though we had successfully used different things/Objects to dynamically include different components.

That's when I found this post which inspired me to wrap my ui:include in a f:subview. And now everything is working great with the following code:

<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>



回答3:


I remember trying to do something similar using a custom tag and FaceletHandler etc. In the end all the little rendering-time issues made it not worth the effort. Mind you I was (and still am :-(...) using facelets for jsf 1.1, so not sure if this is better in the later versions.

How dynamic / how many different facelets do you have to deal with? The reason I ask is that you could (to borrow a term from the compiler wizards) unroll your loop. Instead of

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

You could do

<custom:panelOneFacelet rendered="#{hasPanel1}" />
<custom:panelTwoFacelet rendered="#{hasPanel2}" />
<!-- etc... -->

And in your facelet, you would have something like :

<c:if test="#rendered" >
    <!-- EVERYTHING IN THE FACELET HERE!!!-->
</c:if>

This sort of low-tech approach is fine for a small controlled set, but if you have a very large and varying set of facelets this may not work.

Might I ask why, b/c sometimes with an understanding of the high-level, SO gurus may suggest much simpler ideas for accomplishing the same goal



来源:https://stackoverflow.com/questions/3362487/dynamic-uiinclude-inside-uirepeat-is-there-a-simple-solution

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!