您如何期望使用BackendDatapRovider进行网格的动态过滤器?我有一个功能齐全的实例,但是我觉得我使它起作用的方式不可能是正确的或至少是预期的方法。 我的应用程序中有一个经理类,可以提供所有数据库通信以及广泛的业务逻辑。我已将BackendDataProvider接口添加到它中,并实现了所需的方法(至少,由于Vaadin文档想要谈论ListDataproviders,我尽可能地弄清楚了)。
public interface AgreementManager extends KendoDataSourceManager<Agreement>, BackEndDataProvider<Agreement, GridFilter> {
}
@Service("agreementManager")
@Transactional(propagation = Propagation.REQUIRED)
public class AgreementManagerImpl extends AbstractManagerImpl implements AgreementManager {
.....
@Override
public void setSortOrders(List<QuerySortOrder> sortOrders) {
}
@Override
public int size(Query<Agreement, GridFilter> query) {
return createQueryDslStatementAndGetData(new GridDataState(
query.getFilter().orElse(null),
null,
0,
0
)).getTotal();
}
@Override
public Stream<Agreement> fetch(Query<Agreement, GridFilter> query) {
List<GridSort> sorts = new ArrayList<>();
query.getSortOrders().forEach(so ->
sorts.add(new GridSort(
so.getDirection() == SortDirection.ASCENDING ? "asc" : "desc",
so.getSorted()
))
);
GridDataState gridDataState = new GridDataState(
query.getFilter().orElse(null),
sorts.toArray(new GridSort[0]),
query.getOffset(),
query.getLimit()
);
QueryDslDataSource<Agreement> test = createQueryDslStatementAndGetData(gridDataState);
return test.getData().stream();
}
@Override
public void refreshItem(Agreement item) {
}
@Override
public void refreshAll() {
}
@Override
public Object getId(Agreement item) {
return Objects.requireNonNull(item).getId();
}
@Override
public Registration addDataProviderListener(DataProviderListener<Agreement> listener) {
return null;
}
}
这是准备网格的Vaadin View类的相关部分:Grid<Agreement> grid = new Grid<>(Agreement.class, false);
layout.add(grid);
grid.setMultiSort(true, Grid.MultiSortPriority.APPEND, true);
grid.setColumnReorderingAllowed(true);
grid.setPageSize(50);
/**
* Create the default header row, and then create the filter header row.
*/
grid.appendHeaderRow();
HeaderRow filterHeaderRow = grid.appendHeaderRow();
GridFilter filter = new GridFilter();
filter.setLogic("and");
ConfigurableFilterDataProvider<Agreement, Void, GridFilter> agreementManagerFilter = agreementManager.withConfigurableFilter();
agreementManagerFilter.setFilter(filter);
grid.setItems(agreementManagerFilter);
//GridLazyDataView<Agreement> gridHolder = grid.setItems(agreementManagerFilter);
{
Select<AgreementStatus> filterField = ComponentUtil
.createSelect(
false,
"",
true,
SpringUtil.getBean(AgreementStatusRepository.class).findAll(
QAgreementStatus.agreementStatus.phase.notIn(List.of(
AgreementStatus.AWARDED_RECEIVED,
AgreementStatus.AWARDED_ACCEPTED,
AgreementStatus.AWARDED_IN_PROCESS
)),
Sort.by("phase")
),
item -> item != null ? item.getDisplayName() : ""
);
filterField.addValueChangeListener(evt -> {
GridFilter gridFilter = new GridFilter();
gridFilter.setField("status.phase");
gridFilter.setValue(evt.getValue().getPhase());
gridFilter.setOperator("eq");
filter.setFilters(new GridFilter[] {
gridFilter
});
/*agreementManagerFilter.setFilter(filter);
agreementManagerFilter.refreshAll();
grid.getDataCommunicator().reset();
grid.getDataProvider().refreshAll();
gridHolder.refreshAll();*/
grid.setItems(agreementManagerFilter);
});
filterHeaderRow.getCell(
grid
.addColumn(item -> ls.getText("objectKey.contractStatus.phase." + item.getStatus().getPhase()), "status.phase")
.setKey("status")
.setHeader(ls.getText("objectKey.agreement.status"))
.setSortable(true)
.setAutoWidth(true)
).setComponent(filterField);
}
{
TextField filterField = ComponentUtil.createTextField(false, "");
filterField.setPlaceholder("Search AgreementNumber...");
filterField.setValueChangeMode(ValueChangeMode.EAGER);
filterField.addValueChangeListener(evt -> {
GridFilter gridFilter = new GridFilter();
gridFilter.setField("agreementNumber");
gridFilter.setValue(evt.getValue());
gridFilter.setOperator("contains");
filter.setFilters(new GridFilter[]{
gridFilter
});
/*agreementManagerFilter.setFilter(filter);
agreementManagerFilter.refreshAll();
grid.getDataCommunicator().reset();
grid.getDataProvider().refreshAll();
gridHolder.refreshAll();*/
grid.setItems(agreementManagerFilter);
});
filterHeaderRow.getCell(
grid
.addColumn("agreementNumber")/*.setKey("agreementNumber")*/
.setHeader(ls.getText("objectKey.agreement.agreementNumber"))
.setAutoWidth(true)
).setComponent(filterField);
}
grid.addColumn(item -> item.getAgreementStyle().getDisplayName(), "agreementStyle").setKey("agreementStyle")
.setHeader(ls.getText("objectKey.agreement.agreementStyle"))
.setAutoWidth(true);
grid.addColumn("agreementType.name")/*.setKey("agreementType")*/.setHeader(ls.getText("objectKey.agreement.contractType"))
.setAutoWidth(true);
.......
要简要解释上面的内容,我创建了一个网格,获取后端提供商的过滤器包装器,设置过滤器,将其设置为网格的项目,然后我配置了一个用于基于所有列的任何列的值动态过滤网格的过滤器行(最终)。该动态过滤器是我正在努力的关键。我想允许我的用户在网格中过滤数据,但是根据他们想要为任何显示的列提供的任何条件,他们希望他们想要。我混淆的关键区域是对过滤场的评论侦听器的评论部分。
/*agreementManagerFilter.setFilter(filter);
agreementManagerFilter.refreshAll();
grid.getDataCommunicator().reset();
grid.getDataProvider().refreshAll();
gridHolder.refreshAll();*/
grid.setItems(agreementManagerFilter);
您可以看到,我的第一个尝试是将过滤器设置在包装的管理器上。这与用于懒惰加载过滤的Vaadin文档 -
Https://vaadin.com/docs/latest/components/grid#lazy-loading- 不幸的是什么都没做。我尝试了其余的评论项目,以尝试强制网格以申请数据,而无效。诚然,刷新了射击正确,我确实知道我自己的刷新未能实施。但是,我不知道我应该如何处理这种刷新,可以回到网格并使数据要求。可以看出,我的逻辑取决于获取过滤器并从提供的查询参数中分类。最终,我的决议是再次调用网格。再次重置我的经理。这确实有效,我得到了我期望的确切结果。我的数据实时过滤并显示我期望的。 我的问题是,这完全是错误的。我以非常回旋的方式强迫预期的结果,我缺少一些明显的结果。我的问题是,使用动态过滤器的vaadin网格和后端dataprovider的预期/预期方法是什么?
通常,您可以使用要过滤的所有字段创建一个过滤器类,因此它可能与您在网格中显示的bean具有很强的相似性。并且可以将过滤器类的实例应用于数据视图,当您将项目设置为网格组件时,该视图将返回。 文档的过滤部分中有一个很好的例子。
Https://vaadin.com/docs/latest/components/grid#filtering