Mam takie pytanie odnośnie nawigacji i dynamicznego ładowania danych w
Managed Beanach.
Do tej pory robiłem prosty workflow, taki że użytkownik klikał
commandLinka lub buttonLinka i wtedy wykonywałem jakąś akcję która
ładowała kolekcje lub inicjalizowała atrybuty. Po czym przechodziła na
jakąś stronę gdzie te dane były używane. I żyłem sobie w sielance;P
Problem pojawia się wtedy gdy ktoś z palca wklepie docelowy link (tam
gdzie chcę przejść), bo wtedy te dane które powinny być
zainicjalizowane wcale nie są i albo mi się nic nie pojawia albo leci
jakiś nullPointer.
Oczywiście mam kilka sposobów, żeby to schakować.
Robię sobie metodę:
public String getFoo(){
// inicjalizuję wszystkie zmienne, kolekcje.
return null;
}
i wołam ją na samym początku storny
<body><f:view><h:outputText value="#{bean.foo}" />... </body>
Inny sposób to powalczenie z anotacjami w Managed Beanach
Mamy do dyspozycji @PostConstruct i takie podobne.
Ale ogólnie obydwa sposoby są lekko rzecz biorąc hakowaniem JSF a nie
praktycznym używaniem.
Czy jest jakiś sposób na wymuszenie wywyłania jakiś metod bean'a przed
wywołaniem linka?
pzdr.
Pamiętam że było coś takiego w SEAMie, tam się dało definiować w XML'u
wołanie metody przed wywołaniem strony, ale aż mi sie dziwne wydaje że
chłopaki z SUN'a o tym nie pomyśleli. I nawet w JSF 1.2 nic o tym nie
ma?
nie tyle w xmlu co w adnotacji.
faktycznie dziwna sprawa ale z tego co pamietam to w jsf nie ma takiego
wsparcia do odpalenia metody przed pokazaniem jakiegos widoku wchodzac
bezposrednio przez url na stronke.
W adnotacji? Co konkretnie masz na myśli? @Factory
W pages.xml dla konkretnego <page/> można wstawić parametr action
wskazujący na metodę, która ma się wykonać przed renderingiem strony.
Pozdrawiam
Szarak
Mozesz zrobic wlasna mape nawigacji (parsujac faces-config?) i nadpisac
1 metodke w ViewHandler, ktore sprawdza czy dane przejscie jest mozliwe.
Pozdrawiam
Mateusz Gałek
> Problem pojawia się wtedy gdy ktoś z palca wklepie docelowy link (tam
> gdzie chcę przejść), bo wtedy te dane które powinny być
> zainicjalizowane wcale nie są i albo mi się nic nie pojawia albo leci
> jakiś nullPointer.
"Przysłuchiwałem się" dyskusji i miałem kilka pomysłów dostępnych w JSF,
ale dobrze zrobiłem, że się nie odezwałem na początku, bo wpadka murowana.
Zastanawiam się nad stwierdzeniem "te dane powinny być zainicjowane".
Jeśli są potrzebne na stronie to gdzieś następuje wywołanie tych danych,
nieprawdaż? Skoro tak, to chociażby w konstruktorze komponentu
zarządzanego istnieje możliwość pobrania danych. Inny sposób to pobranie
tych danych w @PostConstruct (nie korzystałem, ale słyszałem, że
istnieje ;-)). Konstruktor jest zbyt wcześnie w stosunku do mechanizmu
DI kontenera, więc raczej odpuściłbym mu, ale @PostConstruct wydaje się
być właściwy.
Jedna uwaga: jedynie wykorzystywane komponenty są inicjowane przez kontener.
Jacek
--
Jacek Laskowski
http://www.JacekLaskowski.pl
> W asp.net jest to banalnie rozwiazane, mianowicie callback Page_load
> jest wywolywany przy kazdym wejsciu na strone, ciekawe dlaczego w jsf
> nie ma czegos takiego, tylko trzeba stosowac jakies hacki..
Czuję, że, zainspirowany komentarzem, znalazłem rozwiązanie - atrybut
beforePhase elementu f:view.
Więcej na
http://jlaskowski.blogspot.com/2007/06/fview-beforephase-i-wywoanie-metody.html
zawsze można dorzucić facelets, ale tam z kolei jest bug i należy
pisać beforPhaseListener zamiast beforePhase. Poza tym beforePhase nie
rozwiązuje problemu kiedy korzystamy z templateów w facelets. A tak z
mojego punktu widzenia to nie można bez nich żyć;P
melon.
> co z uzytkownikami myFaces, nie jestem pewien ale biezace wydanie nie
> jest oparte chbya o jsf 1.2, gdzie mozna stosowac beforePhase w f:view ?
Wtedy pozostaje rejestrowanie PhaseListenera w faces-config.xml i....no
właśnie tutaj sprawdzanie, co będzie wywoływane (dużo ifów) i wykonanie
odpowiedniej akcji. Inaczej sobie tego nie wyobrażam.