« Atrás

RichFaces, trabajando con tablas (4): Acciones dentro de una tabla paginada

Este artículo describe cómo incorporar acciones dentro de una tabla paginada que NO almacena en memoria todos los objetos que gestiona. Este artículo es una continuación de "RichFaces, trabajando con tablas (2)", hace evolucionar el ejemplo que se describe en ese artículo para que pueda manejar acciones. Resuelve un error muy habitual como se trabaja con tablas y acciones en RichFaces, "No component found to process".

Introducción

La definición de acciones dentro de las filas de una tabla paginada se realiza mediante los componentes RichFaces commandButton o commandLink, por ejemplo:

<a4j:commandlink ...="">
...
</a4j:commandlink>

Estos componentes son capaces de enviar peticiones al servidor. En este punto surgen varias preguntas:

  • ¿Qué información se envía al servidor?
  • ¿Qué tiene que hacer el servidor como respuesta?

Si el componente commandButton o commandLink NO se personaliza de forma alguna, cuando se hace click sobre uno de estos elementos se envía toda la información de la página, entre ellas la tabla.
Se pasa por las distintas fases del ciclo de vida. Se ejecuta el método walk() de forma innecesaria (la variable detached NO permite que se acceda a la base de datos).

Optimización en el envío de la petición

Para evitar el envío de información innecesaria en la petición se debe trabajar con alguno de los atributos asociados a estos componentes:

  • ajaxSingle: debemos activarlo a true. La petición ajax que desencadeno sólo envía la información de la acción.
  • reRender: debemos indicar cuáles son los componentes JSF de la vista que queremos actualizar cuando se genere la respuesta.
  • limitToList: debemos activarlo a true. De esta forma conseguimos que si algún outputpanel de RichFaces tiene activado el atributo ajaxRendered a true NO lo tenga en cuenta.

Se obtiene algo así:

...
<a4j:commandlink ajaxsingle="true" id="accion" limittolist="true" rerender="dato01">
     ...                                                        
</a4j:commandlink>
...

Si se quiere enviar información del elemento seleccionado al servidor, como parte de la petición, se puede utilizar el componente a4j:actionparam y su atributo assignTo de la siguiente forma:

<a4j:commandlink ajaxsingle="true" id="accion" limittolist="true" rerender="dato01">
    <h:outputtext value="#{f.concepto}">
    <a4j:actionparam assignto="#{expedienteForm3.f.concepto}" name="concepto" value="#{f.concepto}">
    </a4j:actionparam>

...
</h:outputtext></a4j:commandlink>

Problema: No component found to process

IMPORTANTE:

Si el modelo trabaja con objetos cuya clave identificadora NO es numérica, por ejemplo una cadena de caracteres:

public class ArticuloDataProvider implements
DataProvider{
...
public class ArticuloDataModel extends SerializableDataModel{

private String currentPk;
...

no funciona:

WARN [AjaxViewRoot] No component found to process as 'ajaxSingle' for clientId ...
WARN [AjaxViewRoot] No component found to process as 'ajaxSingle' for clientId ...
WARN [AjaxViewRoot] No component found to process as 'ajaxSingle' for clientId ...

 

La aplicación no responde a las acciones definidas dentro de la tabla.
El problema se produce porque cuando el framework intenta recuperar el elemento que lanza la acción, NO lo encuentra.
Para solventar el problema se debe definir un conversor que pasa de cadena a cadena y pasárselo al datatable mediante el atributo rowKeyConverter.

public class Conversor implements Converter{
    public Object getAsObject(FacesContext context,
                  UIComponent component,String value) {
        return value;
    }
    public String getAsString(FacesContext context,
              UIComponent component,Object value){       
        return value.toString();
    }
}


Definición del conversor en configuración:

<converter>
   <converter-id>conversor</converter-id>
   <converter-class>
          es.ematiz.conversores.Conversor
   </converter-class>
</converter>

Se usa en el dataTable de la siguiente forma:

...
 <rich:dataTable id="tabla” rowKeyVar="rowIndex"
                rowKeyConverter="conversor">
   ...
 </rich:dataTable>
...

 

Comentarios
URL de Trackback:

comments powered by Disqus