PrimeFaces LazyDataModel的load方法中更新JSF growl消息不生效求助
问题根因
- 组件使用错误:你使用了标准JSF的
h:dataTable,但lazy="true"是PrimeFaces<p:dataTable>的专属属性,h:dataTable完全不支持懒加载逻辑,也不会触发你重写的LazyDataModel.load()方法,自然不会生成对应消息。 - 消息生成时机不对:即便替换为
p:dataTable,load()方法会在页面渲染阶段的组件编码环节执行,此时FacesContext的消息队列已经完成了本次请求的处理,新增的消息不会被自动捕获,哪怕p:growl开启了autoUpdate="true"也无法读取到该阶段新增的消息。
修复方案
1. 替换懒加载数据表格组件
将xhtml页面中的h:dataTable替换为PrimeFaces的p:dataTable,保留原有列配置:
<!-- 替换原有h:dataTable代码 --> <p:dataTable value="#{cData.mobiles}" var="mobile" border="2" paginator="true" rows="10" lazy="true" id="mobileTable"> <p:column> <f:facet name="header">Name</f:facet> #{mobile.companyname} </p:column> <p:column> <f:facet name="header">Model Number</f:facet> #{mobile.modelnumber} </p:column> <p:column> <f:facet name="header">Color</f:facet> #{mobile.color} </p:column> <p:column> <f:facet name="header">Quantity</f:facet> #{mobile.quantity} </p:column> <p:column> <f:facet name="header">Price</f:facet> #{mobile.price} </p:column> </p:dataTable>
注意:原有命名空间c对应http://java.sun.com/jsf/core,标准前缀为f,可以保持不变也可以统一修改为f避免歧义。
2. 改造load方法的消息更新逻辑
在load方法中添加完FacesMessage后,手动触发growl组件的ajax更新,强制页面读取最新的消息队列:
@Override public List<Mobile> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) { List<Mobile> data = new DataRepo().getMobileData(); mobiles.setRowCount(data.size()); FacesContext facesContext = FacesContext.getCurrentInstance(); // 可选:清空同ID的历史消息,避免重复提示 Iterator<FacesMessage> msgIterator = facesContext.getMessages("growl-sticky"); while (msgIterator.hasNext()) { msgIterator.next(); msgIterator.remove(); } // 添加新消息 facesContext.addMessage("growl-sticky", new FacesMessage(FacesMessage.SEVERITY_INFO, "加载完成", "共查询到"+data.size()+"条记录")); // 手动触发growl组件更新 PrimeFaces.current().ajax().update("growl-sticky"); return data; }
如果使用PrimeFaces 6.0以下版本,替换更新代码为:
RequestContext.getCurrentInstance().update("growl-sticky");
内容的提问来源于stack exchange,提问作者Jainesh kumar
相关产品推荐
相关产品推荐

