2012-08-12 56 views
6

tengo esta sencilla página:Primefaces DataTable, la carga diferida y CommandButton por fila

<h:form id="form"> 

    <p:dataTable value="#{testBean.unitTypeModel}" var="elem" lazy="true" rows="10"> 
     <p:column headerText="class">#{elem.class.simpleName}</p:column> 
     <p:column headerText="code">#{elem.code}</p:column> 
     <p:column headerText="description">#{elem.description}</p:column> 
     <p:column headerText="action"> 
      <p:commandButton action="test2" icon="ui-icon ui-icon-wrench" value="edit"> 
       <f:setPropertyActionListener target="#{testBean.selection}" value="#{elem}"/> 
      </p:commandButton> 
     </p:column> 
    </p:dataTable> 

    <p:commandButton action="test2" icon="ui-icon ui-icon-wrench"/> 

</h:form> 

y la CommandButton dentro DataTable no funciona, tan solo se actualiza la página. pero el exterior está funcionando.

si cambio value y lazy esta manera:

<h:form id="form"> 

    <p:dataTable value="#{testBean.unitTypeModel.load(0, 10, null, null, null)}" var="elem" lazy="false" rows="10"> 
     <p:column headerText="class">#{elem.class.simpleName}</p:column> 
     <p:column headerText="code">#{elem.code}</p:column> 
     <p:column headerText="description">#{elem.description}</p:column> 
     <p:column headerText="action"> 
      <p:commandButton action="test2" icon="ui-icon ui-icon-wrench" value="edit"> 
       <f:setPropertyActionListener target="#{testBean.selection}" value="#{elem}"/> 
      </p:commandButton> 
     </p:column> 
    </p:dataTable> 

    <p:commandButton action="test2" icon="ui-icon ui-icon-wrench"/> 

</h:form> 

la CommanButton dentro DataTable funciona como un encanto.

alguien sabe por qué?

¿es un error?

estoy en

  • Glassfish 3.1.2
  • JSF 2.1.11 (Mojarra)
  • PrimeFaces 3.4-SNAPSHOT

Respuesta

7

descubierto que el modelo de datos debe ser el vago misma instancia en la solicitud de devolución, incluso una nueva instancia con los mismos valores no funcionará. por lo tanto, se debe proporcionar desde al menos un @ViewScoped bean.

+1

Esto no es del todo cierto: es útil si la misma instancia de 'LazyDataModel' se encuentra en el sesión mediante el uso de '@ ViewScoped', pero también puede usar' @ RequestScoped'. El punto es que el método 'isRowAvailable()' debe devolver verdadero cuando se evalúa en 'APPLY_REQUEST_VALUES' y el campo' pageSize' debe contener un valor mayor que cero. Logré esto extendiendo 'LazyDataModel' mientras sobrecargaba dos métodos:' isRowAvailable() ', aquí llamo' load (...) 'y aplico el resultado a' setWrappedData() 'y el segundo método' setRowIndex (int rowIndex) 'donde establecí el' pageSize' en mi valor predeterminado – uvo

1

Han pasado cuatro años desde que se publicó esta pregunta, pero el problema aún permanece en PrimeFaces 6.0.

Voy a publicar una solución para aquellos que no quieren (o no pueden) usar beans ViewScoped.

La premisa es: "no se puede colocar ningún elemento" ajaxified "dentro de una tabla de datos perezosa vinculada a cosas de RequestScoped". Nunca. Tenga en cuenta que cualquier cosa que arroje una llamada ajax nunca funcionará.

Así que el primer paso es tomar la llamada ajax fuera de la tabla de datos. Lo haremos usando un RemoteComand. Usted puede colocar este RemoteCommand cualquier lugar fuera del DataTable (dentro de un formulario, por supuesto)

<p:remoteCommand name="remoteCall" action="#{bean.doStuff()}"> 
</p:remoteCommand> 

Ahora, todo lo que tenemos que hacer es llamar a este RemoteCommand desde el interior del DataTable. Estoy usando un enlace para realizar la llamada de JavaScript, pero se puede usar un botón o lo que quiera:

<p:column> 
    <p:link value="#{item.id}" href="#" onclick="remoteCall([{name:'id', value:#{item.id}}])"> 
    </p:link> 
</p:column> 

Este enlace proporciona una manera de llamar a la función javascript "RemoteCall", que llevará a cabo la llamada AJAX a "bean.doStuff()".

Tenga en cuenta que el evento onClick contiene no solo la llamada javascript a "remoteCall" sino que también contiene una matriz de parámetros con un solo param, llamada "id" con un valor "# {item.id}". Esto permitirá que RemoteCommand envíe un param llamado "id" al bean de respaldo.

Dentro del método "hacerTarea" que tendrá que recuperar el "id" valor de parámetro:

public void doStuff() { 

    String id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"); 

} 
Cuestiones relacionadas