2017-07-18 1 views
1

Je travaille avec une nouvelle application écrite en version 8 (en cours de test avec 8.1.0.rc2).Grille SelectionMode.MULTI ne contient pas la case à cocher d'en-tête pour sélectionner tout pour BackEndDataProvider

Le problème entoure la case à cocher "Sélectionner tout" qui apparaît dans l'en-tête d'un Grid lorsque vous utilisez SelectionMode.MULTI. En particulier, le problème est que la case à cocher apparaît et fonctionne comme prévu lorsque le DataProvider implémente InMemoryDataProvider, mais la case à cocher n'apparaît pas lorsque le DataProvider implémente BackEndDataProvider.

Le code suivant crée deux grilles qui ne diffèrent que si elles utilisent InMemory ou BackEnd:

public class Test { 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getName() { 
     return name; 
    } 
    private String name; 
} 

public class TestView extends BaseView { 
    public TestView() { 
     super("Test"); 
     addComponent(new TestGrid(new TestDataProvider0())); 
     addComponent(new TestGrid(new TestDataProvider1())); 
    } 
} 

public class TestGrid extends Grid<Test> { 
    public TestGrid(DataProvider<Test, ?> dataProvider) { 
     setHeightByRows(4); 
     setSelectionMode(SelectionMode.MULTI); 
     setDataProvider(dataProvider); 
     addColumn(Test::getName).setCaption("Name"); 
    } 
} 

public class TestDataProvider0 extends AbstractDataProvider<Test, SerializablePredicate<Test>> implements 
     BackEndDataProvider<Test, SerializablePredicate<Test>> { 
    public Stream<Test> fetch(Query<Test, SerializablePredicate<Test>> query) { 
     List<Test> tests = new ArrayList<>(query.getLimit()); 
     for (int i = 0; i < query.getLimit(); i++) { 
      Test test = new Test(); 
      test.setName(String.valueOf(query.getOffset() + i)); 
      tests.add(test); 
     } 
     return tests.stream(); 
    } 
    public int size(Query<Test, SerializablePredicate<Test>> query) { 
     return 100; 
    } 
    public void setSortOrders(List<QuerySortOrder> sortOrders) { 
    } 
} 

public class TestDataProvider1 extends AbstractDataProvider<Test, SerializablePredicate<Test>> implements 
     InMemoryDataProvider<Test> { 
    public Stream<Test> fetch(Query<Test, SerializablePredicate<Test>> query) { 
     List<Test> tests = new ArrayList<>(query.getLimit()); 
     for (int i = 0; i < query.getLimit(); i++) { 
      Test test = new Test(); 
      test.setName(String.valueOf(query.getOffset() + i)); 
      tests.add(test); 
     } 
     return tests.stream(); 
    } 
    public int size(Query<Test, SerializablePredicate<Test>> query) { 
     return 100; 
    } 
    public SerializablePredicate<Test> getFilter() { 
     return null; 
    } 
    public void setFilter(SerializablePredicate<Test> filter) { 
    } 
    public SerializableComparator<Test> getSortComparator() { 
     return null; 
    } 
    public void setSortComparator(SerializableComparator<Test> comparator) { 
    } 
} 

Voici comment les grilles sont rendus: Screenshot

Ai-je raté une étape critique dans la mise mon fournisseur de données/ma grille BackEnd? Le related documentation ne semble pas résoudre ce problème.

Y at-il un problème connu lié à cela?

Est-ce que tout sélectionner n'est pas disponible à la conception? De toute évidence, cela pourrait vraiment interagir mal avec le concept de chargement paresseux sur un grand nombre de données ...

+1

J'ai fait un échantillon rapide, pas de filtres, rien de sophistiqué, en utilisant 'DataProvider.ofCollection (p eople) 'et il se comporte normalement. Pouvez-vous s'il vous plaît partager un [sscce] (http://sscce.org) qui reproduit votre problème? – Morfic

+0

@Morfic Je vous remercie de jeter un coup d'oeil et d'indiquer que cela devrait fonctionner. Je vais commencer à extraire des trucs du code pour voir où est le problème. – Rob

+0

@Morfic La question a été réécrite sur la base d'une enquête plus approfondie. Il semble que cela fonctionne avec un DataProvider qui implémente InMemoryDataProvider, mais ne fonctionne pas lorsque BackEndDataProvider est implémenté à la place. Une idée pourquoi? – Rob

Répondre

1

MultiSelectionModelImpl a cette méthode:

protected void updateCanSelectAll() { 
    switch (selectAllCheckBoxVisibility) { 
    case VISIBLE: 
     getState(false).selectAllCheckBoxVisible = true; 
     break; 
    case HIDDEN: 
     getState(false).selectAllCheckBoxVisible = false; 
     break; 
    case DEFAULT: 
     getState(false).selectAllCheckBoxVisible = getGrid() 
       .getDataProvider().isInMemory(); 
     break; 
    default: 
     break; 
    } 
} 

Cela indique que le comportement par défaut pour non en mémoire les fournisseurs ne doivent pas afficher la case à cocher select-all, mais que ce comportement peut être remplacé en définissant la visibilité sur VISIBLE.

Peaufiner le code original ici:

public class TestGrid extends Grid<Test> { 
    public TestGrid(DataProvider<Test, ?> dataProvider) { 
     setHeightByRows(4); 
     MultiSelectionModel<Test> selectionModel = (MultiSelectionModel<Test>) setSelectionMode(SelectionMode.MULTI); 
     selectionModel.setSelectAllCheckBoxVisibility(SelectAllCheckBoxVisibility.VISIBLE); 
     setDataProvider(dataProvider); 
     addColumn(Test::getName).setCaption("Name"); 
    } 
} 

Plus précisément, cet appel est nécessaire pour la case à cocher apparaître pour les fournisseurs de données qui mettent en œuvre BackEndDataProvider:

MultiSelectionModel<Test> selectionModel = (MultiSelectionModel<Test>) setSelectionMode(SelectionMode.MULTI); 
selectionModel.setSelectAllCheckBoxVisibility(SelectAllCheckBoxVisibility.VISIBLE); 

Avec ce changement, le select-tout case à cocher apparaît maintenant: Fixed screenshot