¿Para qué se pueden utilizar <f:metadata>, <f:viewParam> y <f:viewAction>?

Resuelto Hanynowsky asked hace 13 años • 2 respuestas

¿Alguien puede aclarar cómo podemos usar este fragmento en general o en un ejemplo del mundo real?

<f:metadata>
    <f:viewParam id="id" value="#{bean.id}" />
    <f:viewAction action="#{bean.init}" />
</f:metadata>
Hanynowsky avatar Jun 17 '11 02:06 Hanynowsky
Aceptado

Parámetros GET del proceso

Gestiona <f:viewParam>la configuración, conversión y validación de los parámetros GET. Es como <h:inputText>, pero luego para parámetros GET.

El siguiente ejemplo

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

hace básicamente lo siguiente:

  • Obtenga el valor del parámetro de solicitud por nombre id.
  • requiredConviértalo y valídelo si es necesario (puede usar atributos validatory converteranidar un <f:converter>y <f:validator>en él como con <h:inputText>)
  • Si la conversión y la validación tienen éxito, configúrelo como una propiedad de bean representada por #{bean.id}valor, o si el valueatributo está ausente, configúrelo como atributo de solicitud en el nombre idpara que esté disponible #{id}en la vista.

Entonces, cuando abre la página, foo.xhtml?id=10el valor del parámetro 10se establece en el bean de esta manera, justo antes de que se represente la vista.

En cuanto a la validación, el siguiente ejemplo establece el parámetro required="true"y permite solo valores entre 10 y 20. Cualquier falla en la validación generará un mensaje que se mostrará.

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

Realizar acciones comerciales sobre parámetros GET

Puedes usar el <f:viewAction>para esto.

<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() {
    // ...
}

Sin embargo , es <f:viewAction>nuevo desde JSF 2.2 (ya <f:viewParam>existe desde JSF 2.0). Si no puede actualizar, lo mejor que puede hacer es utilizarlo <f:event>.

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

Sin embargo, esto se invoca en cada solicitud. Debe verificar explícitamente si la solicitud no es una devolución de datos:

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

Si también desea omitir los casos de "Error de conversión/validación", haga lo siguiente:

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

Usar <f:event>esta forma es, en esencia, una solución/truco, es exactamente por eso que se <f:viewAction>introdujo en JSF 2.2.


Pasar parámetros de vista a la siguiente vista

Puede "pasar" los parámetros de vista en los enlaces de navegación configurando includeViewParamsel atributo trueo agregando includeViewParams=trueun parámetro de solicitud.

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

que genera con el <f:metadata>ejemplo anterior básicamente el siguiente enlace

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

con el valor del parámetro original.

Este enfoque solo requiere que tambiénnext.xhtml tenga un parámetro en el mismo parámetro; de lo contrario, no se pasará.<f:viewParam>


Utilice formularios GET en JSF

También se <f:viewParam>puede utilizar en combinación con formularios GET "HTML simple".

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

Básicamente con este @RequestScopedfrijol:

private String query;
private List<Result> results;

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

Tenga en cuenta que <h:message>es para HTML <f:viewParam>, no para HTML simple <input type="text">. También tenga en cuenta que el valor de entrada se muestra #{param.query}cuando #{bean.query}está vacío, porque de lo contrario el valor enviado no se mostraría en absoluto cuando hay un error de validación o conversión. Tenga en cuenta que esta construcción no es válida para los componentes de entrada JSF (ya lo está haciendo "bajo las sábanas").


Ver también:

  • ViewParam frente a @ManagedProperty (valor = "#{param.id}")
  • Comunicación en JSF 2.0: procesamiento de parámetros de solicitud GET
BalusC avatar Jun 16 '2011 20:06 BalusC

Envíe parámetros desde la Vista a otra Vista, desde la Vista del remitente a la Vista del receptor use viewParam e includeViewParams=true

En el remitente

  1. Declarar que se enviarán los parámetros. Podemos enviar Cadena, Objeto,…

Remitente.xhtml

<f:metadata>
      <f:viewParam name="ID" value="#{senderMB._strID}" />
</f:metadata>
  1. Enviaremos el ID del parámetro, se incluirá a “includeViewParams=true”cambio Cadena del evento del botón de clic Botón de clic para activar senderMB.clickBtnDetail(dto) con dto de senderMB._arrData

Remitente.xhtml

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

En senderMB.clickBtnDetail(dto) asignamos _strID con el argumento que obtuvimos del evento de botón (dto), aquí esto es Sender_DTO y lo asignamos a senderMB._strID

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

El enlace al hacer clic se convertirá enhttp://localhost:8080/my_project/view/Receiver.xhtml?*ID=12345*

En recever

  1. Obtener viewParam Receiver.xhtml En Receiver declaramos f:viewParam para obtener el parámetro de la solicitud de obtención (recibir), el nombre del parámetro del receptor debe ser el mismo que el del remitente (página)

Receptor.xhtml

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

Obtendrá el ID de parámetro de la Vista del remitente y lo asignará a Receiver_MB._strID

  1. Usar viewParam En Receiver, queremos usar este parámetro en la consulta SQL antes de renderizar la página, de modo que usemos el evento preRenderView. No vamos a utilizar el constructor porque se invocará antes de recibir viewParam. Entonces agregamos

Receptor.xhtml

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

en f:etiqueta de metadatos

Receptor.xhtml

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

Ahora queremos usar este parámetro en nuestro método de lectura de base de datos, está disponible para usar

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   
}
vuvo avatar Sep 12 '2020 15:09 vuvo