2013-02-19 10 views
10

JSF 2.0, 2.0.1, Mojarra PrimeFaces 3.4.1Pierwsze podkładką wartość Bean z JavaScript

Istnieją podobne pytania, ale potrzebuję czegoś. jeszcze; Funkcja javascript musi czekać na metodę komponentu bean, która wypełnia zmienną, która ma być ściągnięta z funkcji js. Chcę powiedzieć, że:

<p:commandLink action="#{statusBean.getStatuses}" oncomplete="afterLoad()"/> 

Zakładając, że funkcja js właśnie pobiera wartość i drukuje ją na ekranie.

function afterLoad() {  
    alert("#{statusBean.size}"); 
} 

I tu jest dziecko urodziny:

@ManagedBean 
@ViewScoped 
public class StatusBean { 
    public int size=0; 
    List<Status> panelList = new ArrayList<Status>(); 
    public void getStatuses() { 
     this.panelList = fillList(); 
     this.size = panelList.size(); //Assuming 3 
    } 
    //getter and setters 
} 

Więc funkcja alarmuje wielkość jako 0, co jest wartością początkową tego, podczas gdy my spodziewaliśmy się zobaczyć 3.

Jak to działa: Jeśli dodam adnotację @PostConstruct do główki fasoli, z pewnością otrzyma ona prawidłowy rozmiar, ponieważ komponent bean jest już zbudowany przed wczytaniem strony. Oznacza to jednak nadmiarowe procesy, których wartość jest po prostu wymagana po działaniu polecenia commandlink. Jak odłożyć funkcję JS? Jakieś pomysły?

+1

Mojarra 2.0.1 jest starożytna. Już ponad 3 lata. Rozważ ulepszanie. W obecnej wersji 2.1.19 jest wiele poprawek i ulepszeń. – BalusC

+0

@BalusC Ok Mam zamiar przejrzeć różnice w wersji, również obie odpowiedzi są poprawne i działa dziękuję i Partlow, ale nie mogłem zdecydować, który z nich powinien być wybrany jako odpowiedź. Czy powinienem wybrać ze względu na zasadę "kto pierwszy, ten lepszy"? Ale serwer mówi, że odpowiedziałeś 1 minutę temu, ale kiedy ostatnio wyglądałem, było to, że najpierw odpowiedział Partlov. Czy to jest w tym samym czasie? –

+0

Wystarczy wybrać ten, który jest dla Ciebie najbardziej pomocny.Odpowiedzi zamieszczone do tej pory nie zawierają dokładnie tych samych informacji. Jeśli chodzi o dokładną odpowiedź czasową, po prostu sprawdź etykietę "odpowiedzianego" znacznika czasu. Ale nie powinieneś brać tego pod uwagę przy wyborze odpowiedzi. To tylko symuluje FGITW. – BalusC

Odpowiedz

17

JSF/EL i HTML/JS nie działają zsynchronizowane. Zamiast tego JSF/EL działa na serwerze WWW i produkuje HTML/JS, który z kolei działa w przeglądarce internetowej. Otwórz stronę w przeglądarce, rightclick i Zobacz źródło. Widzisz, nie ma jednej linii JSF/EL. To jeden i wszystkie HTML/JS. Na miejsce swojej funkcji JS, zobaczysz:

function afterLoad() {  
    alert("0"); 
} 

Dokładnie to funkcja JS się powoływać na kompletne swojego działania przycisku polecenia. Rezultat jest w pełni oczekiwany.

Zasadniczo, chcesz, aby JSF ponownie renderował ten fragment JS.

<p:commandLink action="#{statusBean.getStatuses}" update="afterLoad" oncomplete="afterLoad()"/> 
<h:panelGroup id="afterLoad"> 
    <h:outputScript> 
     function afterLoad() {  
      alert("#{statusBean.size}"); 
     } 
    </h:outputScript> 
</h:panelGroup> 

W zależności od konkretnych wymagań funkcjonalnych, o których nic nie mówiono, mogą występować bardziej eleganckie sposoby. Na przykład: RequestContext#execute(), <o:onloadScript>, itp.

+0

BalusC, jesteś rock :) – Anatoly

+2

To jest stary wątek .. Ale mam pytanie .. Jak to osiągnąć, jeśli używam zewnętrznego pliku javascript? Proszę pomóż mi. – hermit

8

EL w twoim JavaScript jest obliczany, gdy strona jest renderowana i możesz zaktualizować jej kontener (jeśli jest w jakimś składniku JSF), ale sugerowałbym inne podejście.

Podczas tworzenia żądania AJAX można dodać parametr wywołania zwrotnego w metodzie getStatuses(). Można użyć Primefaces za metodę RequestContext użytkową addCallBackParam() na to:

public void getStatuses() { 
    this.panelList = fillList(); 
    this.size = panelList.size(); 
    RequestContext.getCurrentInstance().addCallBackParam("size", this.size); 
} 

i można użyć tego parametru w xhtml:

<p:commandLink action="#{statusBean.getStatuses}" oncomplete="afterLoad(xhr, status, args)"/> 

<script type="text/javascript"> 
    function afterLoad(xhr, status, args) {  
    alert(args.size); 
    } 
</script> 
+0

Dzięki za tę wspaniałą odpowiedź, pomogłeś mi dzisiaj bardzo dużo, mój przyjacielu! –

+0

Nie ma za co. – partlov

+0

Witaj ponownie, mam problem z 'addCallBackParam'. Działa doskonale, gdy używa się 'afterLoad (xhr, status, args)' przy pierwszym wywołaniu. Ale jeśli chcę wywołać go po raz drugi używając tego samego 'getStatuses()', w metodzie afterLoad 'size' staje się' niezdefiniowanym'. Wygląda na to, że nie może poprawnie dodać parametru callback podczas drugiego wywołania. Co mam na myśli z drugim wywołaniem: na przykład użytkownik dodaje status, a afterLoad działa z powodzeniem, ale jeśli użytkownik usunie status, zdefiniowałem 'remotecommand', który wywołuje' statusBean.getStatuses' i ma onConcomplete = " afterLoad (xhr, status, args) '. –

Powiązane problemy