ADF af:table过滤失效排查及方案咨询(JDev11.1.1.7.0)
我来帮你排查这个ADF表格过滤的问题,一步步拆解错误点,再给你个更省心的实现方案——毕竟在11.1.1.7这个版本上,我踩过不少类似的坑😉
一、你的托管Bean代码里的几个关键错误
countryName未绑定页面输入组件:你在Bean里定义了RichInputText countryName,但页面里完全看不到对应的af:inputText绑定!这直接导致countryName.getValue()大概率是null,过滤条件根本没传进去,自然不会有过滤结果。- 过滤条件更新不规范:你直接修改了
filterQD.getFilterCriteria()返回的Map,但没有调用filterQD.setFilterCriteria(filterCriteria)来确认更新,ADF可能不会识别到这个修改。 - 刷新逻辑不到位:虽然你加了
addPartialTarget局部刷新表格,但没有主动触发绑定的View Object执行查询,数据可能不会同步更新。
二、原生过滤失效的可能原因
你提到原生设置filterVisible="true"和filterable="true"没效果,大概率是这几个配置没到位:
- View Object查询配置缺失:你的
PaisUVOVO需要预先在查询面板中添加NewsiteOxiPaisesNome作为可查询条件,否则原生过滤无法生成对应的SQL语句。 - 表格与查询对象的绑定不匹配:
filterModel="#{bindings.PaisUVOQuery.queryDescriptor}"这个表达式要确保对应的Data Control中存在PaisUVOQuery查询对象,且和表格绑定的VO关联正确。 - 列的
filterable属性配合问题:你给目标列设置了filterable="true",但表格的全局filterable属性没设为true(你的代码里表格没加这个属性),原生过滤的全局开关没打开。
三、修复你的现有代码(快速解决)
1. 先补全页面的输入组件
在过滤按钮前添加绑定到Bean的输入框:
<af:inputText id="it_countryFilter" binding="#{pageFlowScope.paisMB.countryName}" placeholder="输入国家名称过滤"/>
2. 修改托管Bean的filterTableAction方法
public void filterTableAction(ActionEvent actionEvent) { RichTable tb1 = this.getTableData(); FilterableQueryDescriptor filterQD = (FilterableQueryDescriptor) tb1.getFilterModel(); // 清空原有过滤条件,避免累积旧条件 Map<String, Object> filterCriteria = new HashMap<>(filterQD.getFilterCriteria()); filterCriteria.clear(); // 获取输入值并做非空校验 String countryFilter = null; if (countryName != null && countryName.getValue() != null) { countryFilter = countryName.getValue().toString().trim(); } if (countryFilter != null && !countryFilter.isEmpty()) { // 注意属性名要和VO中的属性完全一致 filterCriteria.put("NewsiteOxiPaisesNome", countryFilter); } // 必须调用set方法更新查询描述符 filterQD.setFilterCriteria(filterCriteria); LOGGER.warning("Filter Criteria : " + filterCriteria); // 触发查询事件 tb1.queueEvent(new QueryEvent(tb1, filterQD)); // 主动刷新VO集合,确保数据更新 BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry(); JUCtrlHierBinding paisBinding = (JUCtrlHierBinding) bindings.get("PaisUVO"); if (paisBinding != null) { paisBinding.executeQuery(); } // 局部刷新表格 AdfFacesContext.getCurrentInstance().addPartialTarget(tb1); LOGGER.warning("OnFilterTable Action is Called : " + filterQD); }
四、更优的原生过滤实现(推荐,符合ADF最佳实践)
其实ADF原生的过滤已经足够好用,完全没必要自己写按钮和Bean,按下面配置即可:
1. 配置View Object查询
在JDeveloper中打开PaisUVO VO,进入Query面板,添加NewsiteOxiPaisesNome作为查询条件,设置匹配方式为LIKE(比如NewsiteOxiPaisesNome LIKE :NewsiteOxiPaisesNome),并确保该条件是可过滤的。
2. 修改表格配置
<af:table value="#{bindings.PaisUVO.collectionModel}" var="row" rows="#{bindings.PaisUVO.rangeSize}" emptyText="#{bindings.PaisUVO.viewable ? 'No data to display.' : 'Access Denied.'}" fetchSize="#{bindings.PaisUVO.rangeSize}" rowBandingInterval="0" styleClass="AFStretchWidth" selectionListener="#{bindings.PaisUVO.collectionModel.makeCurrent}" rowSelection="single" id="t1" scrollPolicy="page" autoHeightRows="0" filterModel="#{bindings.PaisUVOQuery.queryDescriptor}" queryListener="#{bindings.PaisUVOQuery.processQuery}" filterVisible="true" filterable="true"> <!-- 全局开启过滤 --> <!-- 其他列保持不变 --> <af:column sortProperty="#{bindings.PaisUVO.hints.NewsiteOxiPaisesNome.name}" sortable="true" filterable="true" headerText="#{bundle['lbl_pais']}" id="c7"> <af:outputText value="#{row.NewsiteOxiPaisesNome}" id="ot2"/> </af:column> </af:table>
3. 可选:添加查询面板(更灵活的过滤)
如果需要多条件过滤或更直观的查询界面,可以加上af:query组件:
<af:query id="q_paisFilter" headerText="过滤国家" queryListener="#{bindings.PaisUVOQuery.processQuery}" queryDescriptor="#{bindings.PaisUVOQuery.queryDescriptor}" resultComponentId="t1"/> <!-- 指定关联的表格ID -->
这样配置后,列头会自动出现过滤输入框,输入内容后按回车或点击过滤图标就会自动触发查询,完全不需要自定义代码,更稳定也更符合ADF的设计思路。
最后验证要点
- 确认VO的
NewsiteOxiPaisesNome属性在查询定义中存在,且是可查询的。 - 检查页面绑定的
PaisUVOQuery是否正确关联了PaisUVOVO。 - 打开ADF日志(设置日志级别为FINE),查看后台生成的SQL语句,确认过滤条件是否正确传递。
内容的提问来源于stack exchange,提问作者Abbas Zahid
相关产品推荐
相关产品推荐

