Voici un article sur le sujet (attention, la signature de la méthode load
de LazyDataModel
a changé depuis l'écriture de l'article : depuis la version 8.0 de PrimeFaces, filters
a maintenant le type Map<String,FilterMeta>
, mais l'idée est toujours la même) et la démo de PrimeFaces qui donne les bases mais qui travaille avec des données dans un tableau et pas dans une base de données. Javadoc de LazyDataModel de la version 8.0 de PrimeFaces.
Pas beaucoup de changements ; dans <p:dataTable>
:
value
est un modèle de type LazyDataModel<CompteBancaire>
au lieu de List<CompteBancaire>
;lazy="true"
;rows="4"
.Le gros travail est de définir la classe qui hérite de la classe LazyDataModel<CompteBancaire>
(classe de Primefaces) et qui sera utilisée pour créer le modèle qui sera passé à la dataTable. La méthode à redéfinir est la méthode load
.
Le plus clair serait d'écrire une classe à part qui hérite de LazyDataModel<CompteBancaire>
.
Le modèle utilisé par la dataTable, instance de cette classe, est créé à la création du backing bean (méthode annotée avec @PostConstruct
).
Page Web qui contient la table :
<p:dataTable value="#{gestionComptes_lazy.model}" rows="4" lazy="true" ...>
Backing bean :
@Named(value = "gestionComptes_lazy") @ViewScoped public class GestionComptesBeanLazy implements Serializable { private LazyDataModel<CompteBancaire> model; @EJB private GestionnaireCompte gestionnaireCompte; public LazyDataModel<CompteBancaire> getModel() { return model; } @PostConstruct public void init() { System.out.println("CREATION LazyComptesDataModel"); this.model = new LazyComptesDataModel(gestionnaireCompte); } ... }
Classe qui implémente LazyDataModel
:
/** * Modèle pour la table "lazy" qui affiche tous les comptes bancaires. */ public class LazyComptesDataModel extends LazyDataModel<CompteBancaire> { private final GestionnaireCompte gestionnaireCompte; public LazyComptesDataModel(GestionnaireCompte gestionnaireCompte) { this.gestionnaireCompte = gestionnaireCompte; } @Override public List<CompteBancaire> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, FilterMeta> filters) { this.setRowCount(gestionnaireCompte.count(filters)); List<CompteBancaire> comptes = gestionnaireCompte.getPageTable(first, pageSize, sortField, sortOrder, filters); return comptes; }
Le backing bean s'appuie sur un EJB session sans état (vous pouvez choisir l'EJB qui a servi jusqu'à maintenant) qui contient une méthode (nommée getPageTable
dans le code ci-dessus) qui retourne les informations depuis la base de données et le gros travail est donc d'écrire cette méthode. Elle retourne les lignes de la base qui doivent être affichées entre les positions m et n (n = m + taille page de la dataTable - 1) dans la table, sachant que la table peut être triée et qu'elle ne contient pas nécessairement toutes les données si l'utilisateur a filtré les données en utilisant des filtres de la dataTable PrimeFaces.
Les informations sur l'état de la table seront fournies par PrimeFaces au moment d'afficher une nouvelle page de la table (elles sont passées en paramètre à la méthode load
ci-dessus) :
Map<String, FilterMeta>
. La clé de la map est le nom du champ utilisé pour le filtrage; par exemple "nom
" si filterBy="#{item.nom}"
. La valeur est de type FilterMeta
. La méthode FilterMeta.getFilterField()
retourne le champ sur lequel porte le filtre. La méthode FilterMeta.getFilterValue()
est la valeur saisie par l'utilisateur pour filtrer.Une petite difficulté supplémentaire : avec PrimeFaces le développeur a le choix des types de filtres (avec l'attribut filterMatchMode
) : startsWith
(valeur par défaut), endsWith
, contains
, exact
, lt
(less than), lte
, gt
, gte
, equals
, in
. La méthode doit donc tenir compte du type de filtre. Le développeur sait bien le type qu'il a choisi pour les colonnes ; n'essayez pas d'écrire une méthode générique qui marcherait pour tous les types de filtre.
Il n'est pas difficile d'écrire un modèle si on suppose que la table ne sera pas triée ni filtrée. Sinon il faut écrire la requête JPA en tenant compte d'un tri et d'un ou plusieurs filtres sur les colonnes. Vous pouvez écrire la version simple (sans filtre ni tri) et la tester.
Si vous avez le temps, ajoutez seulement ensuite le tri et les filtres en vous aidant d'exemples trouvés sur le Web. Vous aurez un exemple dans le projet NetBeans exporté sous la forme d'un fichier zip, donné à la fin du TP.