2015-09-21 2 views
0

J'ai trouvé un problème intéressant, et je me demande si j'utilise mal ou néglige quelque chose. J'ai un grand CellTable qui est défilement vertical. Je veux montrer toutes les lignes à la fois au lieu de la pagination traditionnelle. Donc, au bas de ma table, j'ai une ligne que l'utilisateur peut cliquer pour charger 50 lignes de plus. J'ai fourni à la table un constructeur de table personnalisé (setTableBuilder (new Builder());). Lorsque l'utilisateur clique sur "charger plus", j'interroge les données, les ajoute à ListDataProvider et appelle table.setVisibleRange (0, dataProvider.getList(). Size()) ;.GWT CellTable reconstruire inutilement des rangées

Je mis une déclaration de journal dans la méthode

@Override 
public void buildRowImpl(Object rowValue, int absRowIndex) { 
} 

pour voir quand il a été construit des lignes. Je remarque qu'il construirait 0-dataProvider.getList(). Size() (toutes les lignes), puis il construirait oldLength-dataProvider.getList(). Size() (les nouvelles lignes). Par exemple, si j'ai 100 lignes et que je charge 50 autres, il va construire 0-150, puis reconstruire 100-50. Ce que je veux, c'est que ce ne soit que pour construire les nouvelles lignes, évidemment. Donc, je commence le débogage pour voir pourquoi il reconstruit la table entière à chaque fois. Ce que je trouve était en com.google.gwt.user.cellview.client.HasDataPresenter il fixerait la « redrawRequired » drapeau true à la ligne 1325:

else if (range1 == null && range0 != null && range0.getStart() == pageStart 
    && (replaceDiff >= oldRowDataCount || replaceDiff > oldPageSize)) { 
    // Redraw if the new data completely overlaps the old data. 
    redrawRequired = true; 
} 

Alors ma question est pourquoi faut-il penser que le nouveau les données chevauchent complètement les anciennes données? Est-ce que j'utilise quelque chose de manière incorrecte, y a-t-il un meilleur moyen? Cela devient assez lent lorsqu'il faut redessiner des milliers de lignes qui n'ont pas besoin d'être redessinées.

Merci, Will

Répondre

1

je pense que, dans cette situation, la seule façon une CellTable peut réagir à l'appel de la méthode setVisibleRange() est de redessiner toutes les lignes.

Vous venez d'informer un CellTable qu'il doit maintenant afficher une nouvelle plage (0-150 lignes) au lieu de la dernière (0-100 lignes). Il n'y a aucune information que les rangées 0-100 restent inchangées et il n'y a aucun besoin de les redessiner.

La chose intéressante est que vous avez trouvé les nouvelles lignes sont mises à jour (reconstruction) deux fois:

Par exemple, si j'ai 100 lignes et une charge de 50 plus il construirait 0-150, puis reconstruire 100-50

J'ai essayé de reproduire ce comportement dans l'exemple le plus petit:

public class ListDataProviderTest implements EntryPoint { 

    private static final int ADD_COUNT = 10; 

    private int nextVal = 0; 

    public void onModuleLoad() { 
     final CellTable<Integer> cellTable = new CellTable<Integer>(); 
     cellTable.addColumn(new TextColumn<Integer>() { 
      @Override 
      public String getValue(Integer object) { 
       return object.toString(); 
      }}); 

     final ListDataProvider<Integer> listDataProvider = new ListDataProvider<Integer>(); 

     listDataProvider.addDataDisplay(cellTable); 

     RootPanel.get().add(cellTable); 
     RootPanel.get().add(new Button("Add more...", new ClickHandler() { 
      @Override 
      public void onClick(ClickEvent event) { 
       List<Integer> list = listDataProvider.getList(); 
       for(int i = 0; i < ADD_COUNT; i++) 
        list.add(nextVal++); 
       cellTable.setVisibleRange(0, list.size()); 
      } 
     })); 
    } 
} 

Mais je reçois toutes les lignes mis à jour une fois.

Pouvez-vous confirmer que cet exemple reproduit le problème ou en fournit un plus précis?

+0

J'ai donc réalisé qu'une partie de l'information contenue dans les 50 nouvelles lignes est chargée async donc quand elle arrive, je l'ai redessinée les nouvelles lignes, c'est pourquoi elle charge toutes les 50 dernières.Je suppose que ce que j'espère trouver est un moyen de forcer la table à augmenter en taille et de ne construire que les nouvelles lignes. – Will

0

AFAIK un CellTable redessine toujours toutes les cellules. Voici comment fonctionne le rendu du CellTable. Bien qu'il redessine toujours toutes les cellules, il est dans la plupart des cas toujours plus rapide que l'utilisation d'un FlexTable et ne met à jour que quelques cellules.

+0

Si vous regardez dans com.google.gwt.user.cellview.client.HasDataPresenter, vous verrez dans la méthode boolean resolvePendingState (JsArrayInteger modifiedRows) privé qu'il calcule quelles lignes ont été modifiées et ce qui est nécessaire pour redessiner – Will

+0

S'il vous plaît montrer vos conclusions, votre opinion ("autant que je sache"), ne m'aide pas à comprendre cela – Will