Per cosa possono essere usati <f: metadati>, <f: viewParam> e <f: viewAction>?


149

Qualcuno può chiarire come possiamo usare in generale, o un esempio nel mondo reale, questo frammento?

<f:metadata>
    <f:viewParam id="id" value="#{bean.id}" />
    <f:viewAction action="#{bean.init}" />
</f:metadata>

Risposte:


288

Elaborazione dei parametri GET

L' <f:viewParam>gestisce l'impostazione, la conversione e la convalida dei parametri GET. È come il <h:inputText>, ma poi per i parametri GET.

Il seguente esempio

<f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
</f:metadata>

fa sostanzialmente quanto segue:

  • Ottieni il valore del parametro di richiesta per nome id.
  • Convertire e validare se necessario (è possibile utilizzare required, validatore convertergli attributi e nido di una <f:converter>e <f:validator>in esso come come con <h:inputText>)
  • Se la conversione e la convalida hanno esito positivo, impostarlo come proprietà bean rappresentata dal #{bean.id}valore o se l' valueattributo è assente, quindi impostarlo come attributo di richiesta sul nome in idmodo che sia disponibile #{id}nella vista.

Pertanto, quando si apre la pagina in foo.xhtml?id=10quel momento, il valore del parametro 10viene impostato nel bean in questo modo, proprio prima del rendering della vista.

Per quanto riguarda la convalida, l'esempio seguente imposta il parametro su required="true"e consente solo valori compresi tra 10 e 20. Qualsiasi errore di convalida comporterà la visualizzazione di un messaggio.

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
</f:metadata>
<h:message for="id" />

Esecuzione di azioni commerciali sui parametri GET

Puoi usare il <f:viewAction>per questo.

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
    <f:viewAction action="#{bean.onload}" />
</f:metadata>
<h:message for="id" />

con

public void onload() {
    // ...
}

Il <f:viewAction>è comunque novità dal JSF 2.2 (il <f:viewParam>esiste già dal JSF 2.0). Se non riesci a effettuare l'upgrade, utilizza <f:event>invece la tua scommessa migliore .

<f:event type="preRenderView" listener="#{bean.onload}" />

Questo è comunque invocato su ogni richiesta. Devi verificare esplicitamente se la richiesta non è un postback:

public void onload() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}

Quando si desidera saltare anche i casi "Conversione / convalida non riuscita", procedere come segue:

public void onload() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
        // ...
    }
}

L'uso di <f:event>questo modo è essenzialmente una soluzione alternativa / hack, ecco perché è <f:viewAction>stato introdotto in JSF 2.2.


Passa i parametri della vista alla vista successiva

È possibile "passare" i parametri di visualizzazione nei collegamenti di navigazione impostando l' includeViewParamsattributo trueo aggiungendo il includeViewParams=trueparametro di richiesta.

<h:link outcome="next" includeViewParams="true">
<!-- Or -->
<h:link outcome="next?includeViewParams=true">

che genera con l' <f:metadata>esempio sopra sostanzialmente il seguente link

<a href="next.xhtml?id=10">

con il valore del parametro originale.

Questo approccio solo richiede che next.xhtmlha anche un <f:viewParam>sullo stesso parametro, altrimenti non sarà passato.


Usa i moduli GET in JSF

La <f:viewParam>può essere utilizzato anche in combinazione con "plain HTML" forme GET.

<f:metadata>
    <f:viewParam id="query" name="query" value="#{bean.query}" />
    <f:viewAction action="#{bean.search}" />
</f:metadata>
...
<form>
    <label for="query">Query</label>
    <input type="text" name="query" value="#{empty bean.query ? param.query : bean.query}" />
    <input type="submit" value="Search" />
    <h:message for="query" />
</form>
...
<h:dataTable value="#{bean.results}" var="result" rendered="#{not empty bean.results}">
     ...
</h:dataTable>

Con sostanzialmente questo @RequestScopedfagiolo:

private String query;
private List<Result> results;

public void search() {
    results = service.search(query);
}

Nota che <h:message>è per <f:viewParam>HTML, non per HTML semplice <input type="text">! Si noti inoltre che il valore di input viene visualizzato #{param.query}quando #{bean.query}è vuoto, altrimenti il ​​valore inviato non verrebbe visualizzato affatto quando si verifica un errore di convalida o di conversione. Si noti che questo costrutto non è valido per i componenti di input JSF (lo sta già facendo "sotto le coperte").


Guarda anche:


@BalusC Quale dovrebbe essere lo scopo di "bean" quando usato insieme a faces-redirect = true? Funzionerà come previsto se l'ambito è impostato su "@RequestScoped"?
Geek,

@Geek: un reindirizzamento crea una nuova richiesta GET. L'ambito del bean di origine e di destinazione è irrilevante. Tuttavia, è necessario prendere in considerazione le possibili implicazioni di una nuova richiesta GET per una richiesta e visualizzare il bean con ambito. Vedere anche stackoverflow.com/questions/7031885/...
BalusC

@BalusC Cosa intendi esattamente con "Dovresti comunque prendere in considerazione le possibili implicazioni di una nuova richiesta GET per una richiesta e visualizzare il bean con ambito".
Geek,

@Geek: saranno spazzati via e ricreati perché il loro scopo finirà e inizierà.
BalusC,

@BalusC. Una risposta completa "Quando è necessario utilizzare una funzione simile a PostConstruct" @ "per visualizzare bean con ambito che non viene richiamato su ogni richiesta, verificare se la richiesta non è un postback". Se non viene richiamato su ogni richiesta, perché verificare se la richiesta è un postback o no?
Uluk Biy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.