¿Para qué se pueden utilizar <f:metadata>, <f:viewParam> y <f:viewAction>?
¿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>
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
. required
Conviértalo y valídelo si es necesario (puede usar atributosvalidator
yconverter
anidar 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 elvalue
atributo está ausente, configúrelo como atributo de solicitud en el nombreid
para que esté disponible#{id}
en la vista.
Entonces, cuando abre la página, foo.xhtml?id=10
el valor del parámetro 10
se 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 includeViewParams
el atributo true
o agregando includeViewParams=true
un 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 @RequestScoped
frijol:
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
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
- 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>
- 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
- 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
- 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
}