2010-07-29 8 views
6

Chcę dynamicznie wybrać facelet, aby wyrenderować jakiś element na mojej liście danych. Pierwsza próba będzie:Dynamic ui: include inside ui: repeat. Czy istnieje proste rozwiązanie?

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

Ale to nie będzie działać, ponieważ src ui: include jest oceniany zbyt wcześnie. Informacje o facelcie są naprawdę dynamiczne, więc nie mogę użyć c: forEach (nie polecam też mieszania z fasetkami). Domyślam się, że wszystko sprowadza się do znalezienia komponentu opartego na komponencie: include alternatywa.

Czy jest coś takiego, czy muszę napisać własną?

+0

Przez wiele lat będziemy walczyć z tym samym problemem. Zastanawiam się, czy mrembisz kiedykolwiek znalazłeś lepsze rozwiązanie z JSF 2?Jeśli nie, możesz udostępnić Ci niestandardowe rozwiązanie? – cyberoblivion

+0

@cyberoblivion wdrożyliśmy własny komponent włączający i dostosowaliśmy UIRepeat do pracy z nim - głównie w celu umożliwienia wielu poziomów zagnieżdżania. Nadal działa w naszych systemach produkcyjnych. Ale i tak odsunęliśmy się od JSF. – mrembisz

+0

, więc rozwiązanie nie jest czymś, co przydałoby się komuś innemu lub nie wolno Ci udostępniać kodu? Bardzo interesuje mnie kod. – cyberoblivion

Odpowiedz

2

c: forEach to rozwiąże, dlaczego nie możesz go użyć?

ciekawy artykuł odnośnie tej kwestii: http://www.ilikespam.com/blog/c:foreach-vs-ui:repeat-in-facelets

+0

Dzięki ale c: forEach jest oceniany raz, kiedy widok jest zbudowany. W moim przypadku to, co jest pod # {panele}, może się zmienić podczas interakcji użytkownika ze stroną. – mrembisz

+0

Zaznaczając to jako odpowiedź: nie będzie działać dla mnie głównie ze względu na wpływ na wydajność, ale będzie w porządku dla większości. Używanie niestandardowego dynamicznego włączania na razie. – mrembisz

0

Pamiętam, starając się zrobić coś podobnego przy użyciu niestandardowego znacznika i FaceletHandler itd W końcu wszystkie małe problemy renderowania w czasie sprawiły, że nie warte wysiłku. Zauważyłem, że byłem (i nadal jestem: - (...) używając facfs dla jsf 1.1, więc nie jestem pewien, czy to jest lepsze w późniejszych wersjach.

Jak dynamiczne/ilu różnych faclines musisz czynienia? pytam o to, że można (pożyczyć termin z kreatorów kompilatora) rozwinąć swoją pętlę. Zamiast

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

można zrobić

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

iw swoim facelet, ty miałoby coś takiego:

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

Ten rodzaj low-tech podejście jest dobre dla małej kontrolowanym zestawie, ale jeśli masz bardzo duże i zmienny zbiór Facelets to może nie działać.

Mogę zapytać dlaczego, b/c czasami ze zrozumieniem wysokim poziomie, SO guru może sugerować znacznie prostszych pomysłów dla osiągnięcia tego samego celu

+0

Zasadniczo wykonujemy formularz biznesowy dostarczony nam jako drzewo pól danych. To, co tutaj opisałeś, było naszą pierwszą próbą, ale okazało się, że jest bardzo zasobochłonne, ponieważ w każdym węźle mieliśmy kompletny zestaw możliwych opcji renderowania. Skończyło się na implementacji naszego własnego tagu include +, który działa dobrze, ale jest trudny do utrzymania ze względu na złożoność i cechy wewnętrzne jsf. Zrobiliśmy to prawie 3 lata temu, a teraz zamierzamy przenieść się do jsf2. Miałem nadzieję, że do tego czasu pojawi się nieoczekiwana alternatywa. – mrembisz

+0

Hmmm .. nie jestem pewien, że rozumiem ... więc lubisz Library {location, name, List books} where Book {name, isbn, Author} where Author {nazwa, wiek, ...} Coś takiego? A chciałbyś otrzymać taką strukturę, aby wygenerować drzewo pól formularzy? ... Muszę to źle, prawda? .. To wydaje się zbyt skomplikowane dla mnie, chciałbym podzielić to wszystko na różne formy i fasolę etc ... –

+0

Masz rację, to jest dokładnie to, co mamy i nie znamy struktury rekordu do czasu wykonania. Jak już powiedziałem, mamy działające, ale dość złożone rozwiązanie. Chciałbym zbadać możliwość zrzucenia naszej niestandardowej logiki jsf include. – mrembisz

4

Chyba uznał, że stosunkowo proste rozwiązanie którego szukałeś.

Ja też zacząłem od ui: include inside a ui: repeat like yours, ale zaakceptowałem, że musiałem użyć ac: forEach, a c: forEach działało świetnie, dynamicznie pobierając inny zestaw xhtml/components obejmują nawet interakcje użytkownika zmieniające rzeczy w Widoku, tak jak myślę, że masz. Wyglądało to tak:

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

Jednak moja ui: param nie działa - każdy element został przekazany włączyłem tę samą „rzecz”/przedmiot mimo że mieliśmy z powodzeniem stosowane różne rzeczy/Obiekty dynamiczne obejmują różne składniki.

To wtedy znalazłem this post, który zainspirował mnie do zawinięcia mojego ui: include in f: subview. A teraz wszystko działa dobrze z następującym kodem:

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

Dzięki, stary! f: Wywiad był dla mnie odpowiedzią! – hbobenicio