我尝试在页面加载时不加载
p:selectOneMenu
项目列表,因为列表太大。我将属性 dynamic="true"
设置为延迟加载,但它始终在页面加载时加载列表。相反,我只想在用户开始打开 p:selectOneMenu
时加载它。
我的xhtml
<p:selectOneMenu id="companyEntity"
value="#{docBean.docIncomingEntity.companyEntity}"
effect="fade"
style="width: 100%"
dynamic="true"
filter="true"
converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{companyBean.loadAllCompaniesList()}"
itemLabel="#{item.name}"
itemValue="#{item}"
var="item"/>
</p:selectOneMenu>
我的豆子
...
public List<CompanyEntity> loadAllCompaniesList() {
return companyDAO.selectAllCompanies();
}
我的DAO
public List<CompanyEntity> selectAllCompanies() {
return em.createQuery("select a from CompanyEntity a order by a.name", CompanyEntity.class)
.getResultList();
}
dynamic
属性是在PrimeFaces 6.2中添加的。
请注意,当页面加载时,
dynamic="true"
的 p:selectOneMenu
属性将调用 bean 中项目的 getter 方法。它不会在初始响应中呈现选项 HTML。当菜单首次打开时,这些选项将使用 Ajax 请求添加到 HTML DOM 树中。
如果您希望延迟加载数据,您应该使用
p:autoComplete
组件。自动完成功能会在输入内容时显示建议。它具有各种选项、可定制内容、多重选择、效果和事件。
参见:
题外话:您当前正在使用
loadAllCompaniesList()
(这基本上是您的 getter 方法)。每次打开菜单时可以多次调用此方法。这意味着您的查询将在每次打开时执行多次。这是一个性能问题。
另请参阅:
您可以通过在支持 bean 中声明该字段来实现“真正的”延迟加载行为:
private List<CompanyEntity> allCompanies;
并将 getter 更改为:
public List<CompanyEntity> loadAllCompaniesList() {
if( allCompanies == null )
{
boolean isAjaxRequest = FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest();
if( isAjaxRequest )
{
allCompanies = companyDAO.selectAllCompanies();
}
}
return allCompanies;
}
这是因为,正如上一篇文章所解释的,Primefaces 将在初始页面请求处理期间调用 getter (
loadAllCompaniesList()
)
没有真正使用数据,然后当真正使用 p:selectOneMenu
时,将进行额外的 AJAX 调用,以加载选项。