156 votes

A quoi peuvent servir <f:metadata>, <f:viewParam> et <f:viewAction> ?

Quelqu'un peut-il préciser comment utiliser cet extrait en général, ou dans un exemple concret ?

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

296voto

BalusC Points 498232

Traiter les paramètres GET

El <f:viewParam> gère la définition, la conversion et la validation des paramètres GET. C'est comme le <h:inputText> mais alors pour les paramètres GET.

L'exemple suivant

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

fait essentiellement ce qui suit :

  • Obtenir la valeur du paramètre de la requête par son nom id .
  • Convertissez-le et validez-le si nécessaire (vous pouvez utiliser la fonction required , validator y converter et d'imbriquer un <f:converter> y <f:validator> comme dans le cas de <h:inputText> )
  • Si la conversion et la validation réussissent, il est alors défini comme une propriété du bean représentée par #{bean.id} ou si la valeur value est absent, alors il est défini comme attribut de requête sur le nom id afin qu'il soit disponible par #{id} dans la vue.

Donc quand vous ouvrez la page en tant que foo.xhtml?id=10 alors la valeur du paramètre 10 sont définis dans le haricot de cette façon, juste avant que la vue ne soit rendue.

En ce qui concerne la validation, l'exemple suivant définit le paramètre à required="true" et n'autorise que les valeurs comprises entre 10 et 20. Tout échec de validation entraînera l'affichage d'un message.

<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" />

Exécution d'une action commerciale sur les paramètres GET

Vous pouvez utiliser le <f:viewAction> pour ça.

<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" />

avec

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

El <f:viewAction> est cependant nouvelle depuis JSF 2.2 (la fonction <f:viewParam> existe déjà depuis JSF 2.0). Si vous ne pouvez pas faire de mise à jour, votre meilleure chance est d'utiliser <f:event> à la place.

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

Elle est cependant invoquée sur chaque demande. Vous devez vérifier explicitement si la requête n'est pas un postback :

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

Si vous souhaitez également ignorer les cas de "Conversion/Validation échouée", procédez comme suit :

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

Utilisation de <f:event> cette façon est essentiellement une solution de contournement, c'est exactement la raison pour laquelle la <f:viewAction> a été introduit dans JSF 2.2.


Passer les paramètres de la vue à la vue suivante

Vous pouvez faire passer les paramètres d'affichage dans les liens de navigation en définissant les paramètres suivants includeViewParams à l'attribut true ou en ajoutant includeViewParams=true paramètre de la demande.

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

qui génère avec le ci-dessus <f:metadata> exemple essentiellement le lien suivant

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

avec la valeur originale du paramètre.

Cette approche ne fait que nécessite que next.xhtml a également a <f:viewParam> sur le même paramètre, sinon il ne sera pas transmis.


Utiliser les formulaires GET dans JSF

El <f:viewParam> peut également être utilisé en combinaison avec les formulaires GET "plain HTML".

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

Avec essentiellement ceci @RequestScoped haricot :

private String query;
private List<Result> results;

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

Notez que le <h:message> est pour le <f:viewParam> et non le simple HTML <input type="text"> ! Notez également que la valeur d'entrée affiche #{param.query} quand #{bean.query} est vide, car sinon la valeur soumise n'apparaîtrait pas du tout en cas d'erreur de validation ou de conversion. Veuillez noter que cette construction n'est pas valable pour les composants de saisie JSF (elle le fait déjà "sous le manteau").


Voir aussi :

0 votes

@BalusC Quelle devrait être la portée de "bean" lorsqu'il est utilisé en conjonction avec faces-redirect=true ? Cela fonctionnera-t-il comme prévu si la portée est fixée à "@RequestScoped" ?

0 votes

@Geek : Une redirection crée une nouvelle requête GET. La portée du bean source et du bean cible n'est pas pertinente. Vous devriez cependant prendre en compte les implications possibles d'une nouvelle requête GET pour un bean à portée de requête et de vue. Voir aussi stackoverflow.com/questions/7031885/

0 votes

@BalusC Que voulez-vous dire exactement par "Vous devez cependant prendre en compte les implications possibles d'une nouvelle requête GET pour un bean scopé de requête et de vue."

1voto

vuvo Points 51

Envoyer des paramètres d'une vue à une autre vue, de la vue émettrice à la vue réceptrice utiliser viewParam et includeViewParams=true

Dans l'expéditeur

  1. Déclare les paramètres à envoyer. Nous pouvons envoyer String, Object,

Sender.xhtml

<f:metadata>
      <f:viewParam name="ID" value="#{senderMB._strID}" />
</f:metadata>
  1. Nous allons envoyer le paramètre ID, il sera inclus avec “includeViewParams=true” en retour Chaîne de l'événement du bouton de clic Activation du bouton de clic senderMB.clickBtnDetail(dto) avec dto de senderMB._arrData

Sender.xhtml

<p:dataTable rowIndexVar="index" id="dataTale"value="#{senderMB._arrData}" var="dto">
      <p:commandButton action="#{senderMB.clickBtnDetail(dto)}" value="" 
      ajax="false"/>
</p:dataTable>

Dans senderMB.clickBtnDetail(dto) nous assignons _strID avec l'argument que nous avons obtenu de l'événement du bouton (dto), ici c'est Sender_DTO et assigné à senderMB._strID.

Sender_MB.java
    public String clickBtnDetail(sender_DTO sender_dto) {
        this._strID = sender_dto.getStrID();
        return "Receiver?faces-redirect=true&includeViewParams=true";
    }

Le lien, une fois cliqué, deviendra http://localhost:8080/my_project/view/Receiver.xhtml?*ID=12345*

Dans le récepteur

  1. Obtenir viewParam Récepteur.xhtml Dans Receiver, nous déclarons f:viewParam pour obtenir le paramètre de la demande get (recevoir), le nom du paramètre du récepteur doit être le même que celui de l'émetteur (page).

Récepteur.xhtml

<f:metadata><f:viewParam name="ID" value="#{receiver_MB._strID}"/></f:metadata>

Il obtiendra l'ID du paramètre de la vue de l'expéditeur et l'assignera au receiver_MB._strID.

  1. Utiliser viewParam Dans Receiver, nous voulons utiliser ce paramètre dans la requête sql avant le rendu de la page, de sorte que nous utilisons l'événement preRenderView. Nous n'allons pas utiliser le constructeur parce que le constructeur sera invoqué avant que viewParam soit reçu. Ainsi, nous ajoutons

Récepteur.xhtml

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

dans la balise f:metadata

Récepteur.xhtml

<f:metadata>
<f:viewParam name="ID" value="#{receiver_MB._strID}" />
<f:event listener="#{receiver_MB.preRenderView}"
            type="preRenderView" />
</f:metadata>

Maintenant nous voulons utiliser ce paramètre dans notre méthode de lecture de base de données, il est disponible pour utiliser

Receiver_MB.java
public void preRenderView(ComponentSystemEvent event) throws Exception {
        if (FacesContext.getCurrentInstance().isPostback()) {
            return;
        }
        readFromDatabase();
    }
private void readFromDatabase() {
//use _strID to read and set property   
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X