我需要根据PrimeFaces LazyDataModel<T>
返回的行数渲染一些组件。
例如,只有当关联的惰性数据模型返回至少一行时,才应呈现<p:panelGrid>
。
<p:panelGrid rendered=#{bean.rowCount gt 0}>
...
...
...
</p:panelGrid>
在下面给出一个懒惰加载的<p:dataList>
。
<p:dataList var="row"
value="#{bean}"
first="0"
rows="10"
paginator="true"
lazy="true">
...
...
...
<p:dataList>
豆很常见:
@Named
@ViewScoped
public class Bean extends LazyDataModel<Entity> implements Serializable
{
@Inject
private BeanService service;
private static final long serialVersionUID = 1L;
@Override
public List<Entity> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters)
{
setRowCount(service.rowCount());
return service.getList(first, pageSize);
}
}
当处理<p:panelGrid>
的{{1}}属性时,由于惰性数据模型不可用,因此不会再呈现给定的rendered
。
如果<p:panelGrid>
和<p:panelGrid>
的顺序互换,但这是一个设计问题而且无法想到,那么正确的事情就会发生。
给定的<p:dataList>
包含用于预览的复杂报告数据列表(与<p:dataList>
,<p:dataTable>
和其他一些组合),然后将其导出到MS-Excel工作簿和文件已下载。
报告数据列表(由<p:panelGrid>
持有)取决于由<p:dataList>
,<p:inputText>
等组成的多个(自定义)过滤器。列表是基于过滤器值更新的AJAX /事件
根据过滤器的值,列表可以随时为空。在任何情况下,如果<p:selectOneMenu>
为空,则不得呈现<p:dataList>
(<p:panelGrid>
只是一个简单示例。还有其他组件。)
如何根据<p:panelGrid>
(最终来自关联数据库)返回的行数来呈现此类组件,而无需执行额外JPA查询以计算可以返回的行数的额外开销过滤器的值(当已经执行了非常复杂/昂贵的报告JPA标准查询时)?
答案 0 :(得分:1)
在load
中设置行数时,您可能会移动
setRowCount(service.rowCount());
进入一个在加载之前执行的方法(或者在行计数的getter中作为最后一种可能性),因为我假设service.rowCount()
没有执行加载本身,或者我错了?
答案 1 :(得分:1)
您的代码问题是您定义模型的方式。由于您定义的Bean类,除非<p:dataList>
我能提供的最好的东西就是拥有一个bean并在其中包含模型。像这样的东西:
public class MainBean {
private SERVICE service;
private SEARCHOBJECT searchObject;
private BaseListDataModel<LISTMODEL> dataModel = new BaseListDataModel<LM>() {
@Override
public List<LM> load(int first,
int pageSize,
String sortField,
SortOrder sortOrder,
Map<String, String> filters) {
List<LM> result = new ArrayList<LM>();
try {
searchObject.setStartIndex(first);//this is used for my own business, you can handle the paging in some other way
searchObject.setPageSize(pageSize);//this is used for my own business, you can handle the paging in some other way
result = getService().search(searchObject);
int rowCount = searchObject.getTotalRecordCount();
this.setRowCount(rowCount);
} catch (BusinessException ex) {
log.error(ex.getMessage(), ex);
saveError(ex);
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
saveError(new UnknownSystemException(ex));
}
return result;
}
};
...
}
我希望这有用。
答案 2 :(得分:1)
list和datatable的示例。 表“更改数据”没有ajax事件。但是当你做一些过滤,排序或其他只刷新表时,你就是用ajax做的。所以你可以监视ajax调用,当ajax调用发生时你可以刷新你的列表。 这里是工作代码(简单示例):
请注意,这不是更新上面列表的命令按钮,您可以使用任何其他ajax命令更改数据表并仍然可以正常工作
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:pe="http://primefaces.org/ui/extensions"
xmlns:p="http://primefaces.org/ui" >
<pe:head title="PrimeFaces Extensions - ShowCase">
<f:facet name="first">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</f:facet>
</pe:head>
<f:view>
<h:form>
<h:panelGrid id="pvis" >
<p:dataList value="#{modelBean.data2}" var="d" rendered="#{ modelBean.data.size() > 0}" >
#{d}|
</p:dataList>
</h:panelGrid>
<p:remoteCommand name="updatelist" update="pvis" />
<p:ajaxStatus onsuccess="updatelist();" />
<p:dataTable value="#{modelBean.data}" var="d" id="table" >
<p:remoteCommand update="pvis" autoRun="true" immediate="true" />
<p:column headerText="Value" >
<p:outputLabel value="#{d}" />
</p:column>
</p:dataTable>
<p:commandButton action="#{modelBean.addRandomData()}" update="table" value="Populate" />
</h:form>
</f:view>
</html>
托管bean:
package com.example.stackoverflow;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@Named
@SessionScoped
public class ModelBean implements Serializable {
private List<String> data = new ArrayList<String>();
private List<String> data2 = new ArrayList<String>();
public List<String> getData() {
return data;
}
public void setData(List<String> data) {
this.data = data;
}
public List<String> getData2() {
return data2;
}
public void setData2(List<String> data2) {
this.data2 = data2;
}
@PostConstruct
public void init() {
for (int i = 0;i < 10;i++) {
Random random = new Random();
data2.add("value:"+random.nextInt());
}
}
public void addRandomData() {
for (int i = 0;i < 10;i++) {
Random random = new Random();
data.add("value:"+random.nextInt());
}
}
}
根据您的评论:
我仍然找不到办法。数据表不适合报告 何时连续生成报告列表
我添加以下解决方案:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:pe="http://primefaces.org/ui/extensions"
xmlns:p="http://primefaces.org/ui" >
<pe:head title="PrimeFaces Extensions - ShowCase">
<f:facet name="first">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</f:facet>
</pe:head>
<f:view>
<h:form>
<p:outputPanel deferred="true" deferredMode="load" >
<p:panelGrid rendered="#{modelBean.rowCount > 0}" columns="1" >
Show me only if Lazy Model has row
</p:panelGrid>
</p:outputPanel>
<p:dataList value="#{modelBean}" lazy="true" var="d" type="unordered" itemType="none" paginator="true" rows="10" styleClass="paginated" >
<f:facet name="header">
Base list
</f:facet>
#{d}
</p:dataList>
</h:form>
</f:view>
</html>
和懒惰模型:
@Named
@SessionScoped
public class ModelBean extends LazyDataModel<String> implements Serializable {
private List<String> data = new ArrayList<String>();
private List<String> data2 = new ArrayList<String>();
public List<String> getData() {
return data;
}
public void setData(List<String> data) {
this.data = data;
}
public List<String> getData2() {
return data2;
}
public void setData2(List<String> data2) {
this.data2 = data2;
}
@PostConstruct
public void init() {
for (int i = 0;i < 10;i++) {
Random random = new Random();
data2.add("value:"+random.nextInt());
}
}
/*public void addRandomData() {
for (int i = 0;i < 10;i++) {
Random random = new Random();
data.add("value:"+random.nextInt());
}
}*/
@Override
public List<String> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
data = new ArrayList<String>();
for (int i = 0;i < pageSize;i++) {
Random random = new Random();
data.add("value:"+random.nextInt());
}
setRowCount(100);
return data;
}
@Override
public List<String> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
data = new ArrayList<String>();
for (int i = 0;i < pageSize;i++) {
Random random = new Random();
data.add("value:"+random.nextInt());
}
setRowCount(100);
return data;
}
}
请注意可选渲染的延迟加载(使用输出面板)。
另一种解决方案是运行远程命令,以更新页面末尾的第一个面板。
注意:要使渲染 false 可见,您必须更新该元素的父级