根据PrimeFaces LazyDataModel <t>返回的行数呈现JSF / PrimeFaces组件</t>

时间:2014-10-09 20:34:19

标签: jsf primefaces jsf-2.2

我需要根据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标准查询时)?

3 个答案:

答案 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 可见,您必须更新该元素的父级