2013-02-19 7 views
10

JSF 2.0, Mojarra 2.0.1, 3.4.1 primefacesOttenere valore backing bean con JavaScript

Non ci sono domande simili, ma ho bisogno di qc. altro; la funzione javascript deve attendere il metodo backing bean, che sta riempiendo la variabile che voleva essere estratta dalla funzione js. Quello che voglio dire è:

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

Supponendo funzione js solo ottenere il valore e la stampa allo schermo.

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

E qui è il ragazzo di compleanno:

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

Quindi funzione avvisa la dimensione come 0, che è il valore iniziale di esso, mentre ci aspettiamo di vedere 3.

Come funziona: Se aggiungo l'annotazione @PostConstruct alla testa del bean, sicuramente ottiene la dimensione corretta, perché il bean è già stato costruito prima del caricamento della pagina. Ma questo significa processi ridondanti, valore appena necessario dopo l'azione commandlink. Quindi, come posticipare la funzione js? Qualche idea?

+1

Mojarra 2.0.1 è antica. Ha già più di 3 anni. Considerare l'aggiornamento. Ci sono molti, molti bugfix e miglioramenti nella versione 2.1.19 corrente. – BalusC

+0

@BalusC Ok Ho intenzione di rivedere le differenze di versione, anche entrambe le risposte sono corrette e funzionano grazie a te e a partlov ma non ho potuto decidere quale scegliere come risposta. Dovrei scegliere in base al primo arrivato, primo servito? Ma il server dice che hai risposto 1 minuto fa, ma quando l'ho guardato per l'ultima volta è stato detto che Partlov ha risposto per primo. È lo stesso tempo? –

+0

Basta scegliere quello che ti è più utile.Le risposte pubblicate finora non forniscono esattamente le stesse informazioni. Per quanto riguarda la timestamp di risposta esatta, basta controllare la descrizione del timestamp "risposta". Ma non dovresti considerare questo nella scelta della risposta. Questo simula solo FGITW. – BalusC

risposta

17

JSF/EL e HTML/JS non sono sincronizzati. Invece, JSF/EL viene eseguito nel server web e produce HTML/JS che a sua volta viene eseguito nel browser. Aprire la pagina nel browser, tasto destro e Visualizza sorgente. Vedete, non esiste una singola riga di JSF/EL. È tutto e tutto HTML/JS. Al posto della funzione JS, vedrete:

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

Esattamente questo JS funzione get invocato sulla completa della vostra azione pulsante di comando. Quindi il risultato è completamente previsto.

In pratica, si desidera consentire a JSF di re-renderizzare quel pezzo di 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> 

A seconda del requisito funzionale concreto, di cui non hai detto nulla, ci possono essere modi più eleganti. Ad esempio, RequestContext#execute(), <o:onloadScript>, ecc.

+0

BalusC, sei rock :) – Anatoly

+2

Questo è un thread vecchio .. Ma ho una domanda .. Come realizzare questo se sto usando un file javascript esterno? Per favore aiutatemi. – hermit

8

EL nel tuo JavaScript viene calcolato quando viene eseguito il rendering della pagina e puoi aggiornare il suo contenitore (se si trova in un componente JSF), ma suggerirei un altro approccio.

Mentre si effettua la richiesta AJAX, è possibile aggiungere il parametro di richiamata nel metodo getStatuses(). È possibile utilizzare il metodo RequestContext utilità di primefaces addCallBackParam() per questo:

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

ed è possibile utilizzare questo parametro in 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

Grazie per questa grande risposta, mi hai aiutato molto oggi, amico mio! –

+0

Prego. – partlov

+0

Ciao di nuovo, ho un problema su 'addCallBackParam'. Funziona perfettamente quando si usa 'afterLoad (xhr, status, args)' alla prima chiamata. Ma se voglio chiamarlo per la seconda volta usando lo stesso 'getStatuses()', nel metodo afterLoad 'size' diventa' indefinito'. Sembra che non possa aggiungere parametri di richiamata correttamente al secondo richiamo. Quello che intendo con la seconda invocazione è: ad esempio, l'utente aggiunge uno stato e afterLoad funziona dopo, ma se l'utente cancella uno stato, ho definito un 'remotecommand' che chiama' statusBean.getStatuses' e ha 'oncomplete = " post-carico (XHR, stato, args) '. –