Comprensione processo / aggiornamento e JSF f: ajax esegue / rende attributi

Quali sono esattamente i process e gli update nei componenti PrimeFaces p:commandXxx ed execute e render in f:ajax tag f:ajax ?

Che funziona al momento della convalida? Che cosa fa l’attributo di aggiornamento anziché aggiornare il valore al componente dal back-end? Elaborare il valore di associazione dell’attributo al modello? Cosa fanno esattamente @this , @parent , @all e @form in entrambi gli attributi?

L’esempio sotto funziona bene, ma sono un po ‘confuso nei concetti di base.

 

L’attributo di process è lato server e può influire solo sugli UIComponent che implementano EditableValueHolder (campi di input) o ActionSource (campi di comando). L’attributo di process indica a JSF, utilizzando un elenco di ID cliente separato da spazi, quali componenti devono essere elaborati esattamente attraverso l’intero ciclo di vita JSF dopo l’invio (parziale) del modulo.

JSF applicherà quindi i valori della richiesta (individuando il parametro di richiesta HTTP in base all’ID client del componente e quindi impostandolo come valore inviato in caso di componenti EditableValueHolder o accodando un nuovo ActionEvent in caso di componenti ActionSource ), eseguire la conversione, la convalida e l’aggiornamento del valori del modello (solo componenti EditableValueHolder ) e infine richiamano l’ ActionEvent coda (solo i componenti ActionSource ). JSF salterà l’elaborazione di tutti gli altri componenti che non sono coperti dall’attributo di process . Inoltre, i componenti il ​​cui attributo di rendered valutato come false durante l’applicazione della fase dei valori di richiesta verranno ignorati come parte della protezione contro le richieste manomesse.

Si noti che è nel caso di componenti ActionSource (come ) molto importante includere anche il componente stesso nell’attributo del process , in particolare se si intende richiamare l’azione associata al componente. Quindi l’esempio seguente che intende elaborare solo determinati componenti di input quando viene invocato un determinato componente di comando non funzionerà:

   

#{bean.foo} solo #{bean.foo} e non #{bean.action} . Dovresti includere anche il componente di comando stesso:

   

Oppure, come apparentemente hai scoperto, usando @parent se sono gli unici componenti che hanno un genitore comune:

     

Oppure, se entrambi sono gli unici componenti del componente UIForm padre, puoi anche usare @form :

     

Questo a volte non è auspicabile se il modulo contiene più componenti di input che vorresti saltare in elaborazione, più spesso nei casi in cui desideri aggiornare un altro componente di input o una sezione UI basata sul componente di input corrente in un metodo ascoltatore Ajax. Ovviamente non si desidera che gli errori di convalida su altri componenti di input impediscano l’esecuzione del metodo del listener ajax.

Poi c’è il @all . Questo non ha alcun effetto speciale nell’attributo di process , ma solo nell’attributo di update . Un process="@all" si comporta esattamente come process="@form" . HTML non supporta comunque l’invio di più moduli contemporaneamente.

Tra l’altro c’è anche un @none che può essere utile nel caso in cui non sia assolutamente necessario elaborare nulla, ma solo aggiornare alcune parti specifiche tramite l’ update , in particolare quelle sezioni il cui contenuto non dipende dai valori inviati o dai listener di azioni. .

Lo standard JSF equivalente al process specifico PrimeFaces è execute da . Si comporta esattamente allo stesso modo, tranne per il fatto che non supporta una stringa separata da virgola mentre i PrimeFaces ne fanno uno (sebbene io personalmente raccomandi di limitarsi a una convenzione separata @parent spazio), né la parola chiave @parent . Inoltre, potrebbe essere utile sapere che @form su @form mentre e @this su @this . Infine, è anche utile sapere che il process supporta i cosiddetti “selettori PrimeFaces”, vedi anche Come funzionano i selettori di PrimeFaces come in update = “@ (. MyClass)”?


L’attributo di update è lato client e può influire sulla rappresentazione HTML di tutti i componenti UIComponent . L’attributo update indica a JavaScript (quello responsabile della gestione della richiesta / risposta ajax), utilizzando un elenco di ID client separato da spazi, quali parti dell’albero HTML DOM devono essere aggiornate come risposta al modulo submit.

JSF quindi preparerà la giusta risposta ajax per quello, contenendo solo le parti richieste da aggiornare. JSF salterà tutti gli altri componenti che non sono coperti dall’attributo update nella risposta ajax, mantenendo così scarso il payload della risposta. Inoltre, i componenti il ​​cui attributo di rendered valutato come false durante la fase di risposta del rendering verranno saltati. Si noti che anche se restituirebbe true , JavaScript non può aggiornarlo nell’albero HTML DOM se inizialmente era false . Avresti bisogno di avvolgere o aggiornare il suo genitore, invece. Vedi anche Ajax update / render non funziona su un componente che ha reso l’attributo .

Di solito, desideri aggiornare solo i componenti che devono essere “aggiornati” sul lato client dopo l’invio (parziale) del modulo. L’esempio seguente aggiorna l’intero modulo principale tramite @form :

        

(nota che l’attributo process è omesso poiché quello predefinito è già @form )

Benché ciò possa funzionare correttamente, l’aggiornamento dei componenti di input e di comando non è necessario in questo esempio particolare. A meno che non modifichiate i valori del modello foo e bar all’interno del metodo action (che a sua volta non sarebbe intuitivo in prospettiva UX), non ha senso aggiornarli. I componenti del messaggio sono gli unici che devono essere realmente aggiornati:

        

Tuttavia, diventa noioso quando ne hai molti. Questo è uno dei motivi per cui esistono i selettori PrimeFaces. Questi componenti del messaggio hanno nell’output HTML generato una class di stile comune di ui-message , quindi dovrebbe anche fare quanto segue:

        

(si noti che è necessario conservare gli ID sui componenti del messaggio, altrimenti @(...) non funzionerà! Di nuovo, vedere Come funzionano i selettori di PrimeFaces come in update = “@ (. myClass)” per i dettagli)

@parent aggiorna solo il componente principale, che quindi copre il componente corrente e tutti i fratelli e i loro figli. Questo è più utile se hai separato il modulo in gruppi sane con ciascuna la propria responsabilità. Il @this aggiornamento, ovviamente, solo il componente corrente. Normalmente, questo è necessario solo quando è necessario modificare uno degli attributi HTML del componente nel metodo di azione. Per esempio

  

Immagina che l’ oncomplete bisogno di lavorare con il value che è cambiato in action , quindi questo costrutto non avrebbe funzionato se il componente non fosse aggiornato, per il semplice motivo che oncomplete è parte dell’output HTML generato (e quindi tutte le espressioni EL in là sono valutati durante la risposta al rendering).

@all aggiorna l’intero documento, che dovrebbe essere usato con attenzione. Normalmente, ti piacerebbe utilizzare una vera richiesta GET per questo invece tramite un link semplice ( o ) o un reindirizzamento-dopo-POST di ?faces-redirect=true o ExternalContext#redirect() . In effetti, process="@form" update="@all" ha esattamente lo stesso effetto di un invio non-ajax (non parziale). In tutta la mia carriera JSF, l’unico caso di utilizzo ragionevole che ho incontrato per @all è quello di visualizzare una pagina di errore nella sua interezza nel caso in cui si verifichi un’eccezione durante una richiesta Ajax. Vedi anche Qual è il modo corretto di gestire le eccezioni JSF 2.0 per i componenti AJAXified?

Lo standard JSF equivalente update specifico PrimeFaces è render da . Si comporta esattamente allo stesso modo, tranne per il fatto che non supporta una stringa separata da virgola mentre i PrimeFaces ne fanno uno (sebbene io personalmente raccomandi di limitarsi a una convenzione separata @parent spazio), né la parola chiave @parent . Entrambi update e @none render default su @none (che è “niente”).


Guarda anche:

  • Come trovare l’ID client del componente per l’aggiornamento / rendering di ajax? Imansible trovare il componente con espressione “foo” a cui si fa riferimento da “bar”
  • Ordine di esecuzione degli eventi quando si preme PrimeFaces p: commandButton
  • Come diminuire il carico utile della richiesta di p: ajax durante ad esempio p: impaginazione dataTable
  • Come mostrare i dettagli della riga corrente da p: dataTable in ap: dialog e update after save
  • Come usare nella pagina JSF? Forma singola? Più forms? Forme annidate?

Se hai difficoltà a ricordare i valori predefiniti (so che ho …) ecco un breve estratto dalla risposta di BalusC:

 Componente |  Invia |  ricaricare
 ------------ |  --------------- |  --------------
 f: ajax |  execute = "@ this" |  render = "@ none"
 p: ajax |  process = "@ this" |  update = "@ none"
 p: commandXXX |  process = "@ form" |  update = "@ none"

Per processo (nella specifica JSF si chiama execute) si dice a JSF di limitare l’elaborazione al componente che viene specificato ogni altra cosa viene semplicemente ignorata.

aggiornamento indica quale elemento verrà aggiornato quando il server risponde alla richiesta.

@tutto : ogni componente viene elaborato / reso.

@questo : il componente richiedente con l’attributo execute viene elaborato / reso.

@form : il modulo che contiene il componente richiedente viene elaborato / reso.

@parent : il genitore che contiene il componente richiedente viene elaborato / reso.

Con Primefaces puoi persino usare i selettori JQuery, guarda questo blog: http://blog.primefaces.org/?p=1867