JSF Primefaces: Update a dataTable open in another

2019-08-22 03:26发布

问题:

I have a simple webapp which allows the user to create transactions, and on another page the user can see all past transactions. I would like:

  • To have the dataTable be up-to-date when I open the past transaction page
  • To update the dataTable when I create a transaction on the creation page

I am not sure if this can be covered by one or two functionalities. Also, I am not sure how to decouple the functionalities. Should the creation of a transaction trigger the refresh of the dataTable, or should the dataTable itself find new entries in the DB ?

The past transactions page:

My TransactionListModel

package model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

import entity.Transaction;

@Named
@SessionScoped
public class TransactionListModel implements Serializable {
    private static final long serialVersionUID = 1L;

    private List<Transaction> txList;

    @PostConstruct
    public void init() {
        txList = new ArrayList<Transaction>();
    }

    public List<Transaction> getTxList() {
        return txList;
    }

    public void clearList(){
        txList = new ArrayList<Transaction>();
    }
}

My Transaction view

<!-- Fill the table before rendering -->
<f:event type="preRenderView" listener="# {transactionListController.findAllTx()}" />

<h:form id="alltxform">
    <p:dataTable id="tableAllTransactions" var="transaction"
                value="#{transactionListModel.txList}">
        <f:facet name="header">Transactions</f:facet>
            <p:column headerText="Id">
            <h:outputText value="#{transaction.id}" />
        </p:column>
    </p:dataTable>
</h:form> 

My TransactionList Controller

@Named
@RequestScoped
public class TransactionListController implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private Logger log;

    @Inject
    private TransactionService txService;

    @Inject
    private TransactionListModel txListModel;

    public void findAllTx() {
        txListModel.clearList();
        txListModel.getTxList().addAll(txService.findAllTx());
    }

    public void reset() {
        if (txListModel.getTxList() != null) {
            txListModel.clearList();
        }
    }
}

The creation page

There is a simple textInputField (bound to a model) with a button:

<h:commandButton id="sendtx" value="Send" styleClass="ui-priority-primary">
    <f:actionListener binding="#{transactionXmlController.sendTx()}" />
</h:commandButton>

The called method:

public void sendTx() {

        FacesMessage message;
        if (!transactionService.sendTx(transactionXmlEditableModel.getXml()).equals("OK"))
            message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "KO");
        else {
            message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", "OK");

        }    
        fc.addMessage(null, message);
    }

So far, this works.

My Questions

  • How do I reload the dataTable with AJAX ?

  • I would like the dataTable to update even if it has been opened in another tab before the creation of a new transaction. How to do this ?

  • How to replace my "f:event type="preRenderView" with a viewAction in order to fill the dataTable before rendering the page ?

回答1:

I'm not sure how you would update the table in another tab, without something like <p:poll> but to update your table with Ajax you can do something like:

<h:commandButton id="sendtx" value="Send" styleClass="ui-priority-primary">
    <f:ajax listener = '#{transactionXmlController.sendTx()}' render="alltxform:tableAllTransactions" />
</h:commandButton>


标签: jsf-2.2