You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Lazy Model分页异常求助:首次进入页面分页按钮未启用

自定义Lazy Model分页按钮首次加载未启用问题排查与解决

使用自定义Lazy Model时遇到以下问题:首次进入xhtml页面,分页按钮处于未启用状态;但对案件列排序后,分页功能恢复正常。数据通过原生查询提取,数据本身无问题,不清楚未排序时分页失效的原因,需要解决。

XHTML代码

<p:dataTable var="expediente"
             value="#{peticionesPendientesBean.lazyModel}"
             rowKey="#{expediente.mCodExpediente}"
             sortBy="#{expediente.t1.id_expediente}" sortOrder="UNSORTED" paginator="true"                                           
             rows="10"
             styleClass="desplegable"
             paginatorTemplate="{CurrentPageReport} 0 Seleccionados {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown} "
             rowsPerPageTemplate="10,20,50,100,200"
             id="tblPendientes" lazy="true" emptyMessage="#{msg.tbl_noRegist}"
             currentPageReportTemplate="#{peticionesPendientesBean.lazyModel.rowCount==1? lbl.tb_exp_pag : lbl.tb_exps_pag}">                                       
                                    
    <p:column headerText="#{lbl.titulo_peticiones_pendientes}"
              sortBy="#{expediente.id_expediente}" id="codExpediente">
        <h:outputText value="#{expediente.getAtributo(nombreAtributos.CODEXPEDIENTE).value} " />
    </p:column>

Java代码(LazyModel的load方法)

/**
 * @param first
 * @param pageSize
 * @param sortField
 * @param sortOrder
 * @param filters
 */
@Override
public List<Expediente> load(int first, int pageSize, String sortField, SortOrder sortOrder,
        Map<String, Object> filters) {

    try {
        System.out.println("usuario" + user.getCentroDirectivo().getCodCentro());
        System.out.println("perfil" + user.getRole());
        System.out.println("peticionesPendientes: " + peticionesPendientes);
        System.out.println("user: " + user);

        if (sortField == null || sortOrder.equals(SortOrder.UNSORTED)) {
            sortField = "id_expediente"; 
            sortOrder = SortOrder.DESCENDING;
        }

        this.dataSource = this.peticionesPendientes.buscarPendientesNativa(user.getCentroDirectivo().getCodCentro(),
                user.getRole(), first, pageSize, sortField, sortOrder);
        System.out.println("datasource" + dataSource.size());
        
        int count = portaFirmaEnvios.buscarPendientesNativaCount(user.getCentroDirectivo().getCodCentro(),
                user.getRole());
        if (count == 0) {
            this.setRowCount(0);
        } else {
            this.setRowCount(count);
        }
        
    } catch (final Exception e) {
        final FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(Cadenas.EVENT,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, Presentacion.ERROR_MSG, ERR.getString("error_con_motor")));
        dataSource = new ArrayList<Expediente>();
        this.setRowCount(dataSource.size());

        logger.log(Level.SEVERE, e.getMessage() + e.getCause(), e);
    }
    return dataSource;
}

问题根源分析

  1. 初始排序状态冲突:xhtml中dataTable设置了sortOrder="UNSORTED",但load方法里手动替换了排序规则,PrimeFaces组件初始化时可能因为状态不匹配,导致分页组件未正确识别总记录数,从而禁用按钮。排序操作触发后,组件重新调用load,此时状态同步,分页功能恢复。
  2. rowCount初始化时机滞后:总记录数仅在load方法中设置,而组件初始化时可能未及时获取到该值,分页按钮因无法判断总页数而保持禁用。

解决方案

方案1:移除xhtml的初始排序配置

让LazyModel完全控制初始排序逻辑,去掉dataTable上的sortBy和sortOrder属性:

<p:dataTable var="expediente"
             value="#{peticionesPendientesBean.lazyModel}"
             rowKey="#{expediente.mCodExpediente}"
             paginator="true"                                           
             rows="10"
             styleClass="desplegable"
             paginatorTemplate="{CurrentPageReport} 0 Seleccionados {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown} "
             rowsPerPageTemplate="10,20,50,100,200"
             id="tblPendientes" lazy="true" emptyMessage="#{msg.tbl_noRegist}"
             currentPageReportTemplate="#{peticionesPendientesBean.lazyModel.rowCount==1? lbl.tb_exp_pag : lbl.tb_exps_pag}">                                       
    <p:column headerText="#{lbl.titulo_peticiones_pendientes}"
              sortBy="#{expediente.id_expediente}" id="codExpediente">
        <h:outputText value="#{expediente.getAtributo(nombreAtributos.CODEXPEDIENTE).value} " />
    </p:column>

方案2:提前初始化rowCount

在LazyModel的构造方法中提前获取总记录数并设置,确保组件初始化时就能拿到正确的总页数:

public class CustomLazyModel extends LazyDataModel<Expediente> {
    private PortaFirmaEnvios portaFirmaEnvios;
    private User user;

    public CustomLazyModel(User user, PortaFirmaEnvios portaFirmaEnvios) {
        this.user = user;
        this.portaFirmaEnvios = portaFirmaEnvios;
        // 初始化时获取总记录数
        try {
            int count = portaFirmaEnvios.buscarPendientesNativaCount(user.getCentroDirectivo().getCodCentro(), user.getRole());
            this.setRowCount(count);
        } catch (Exception e) {
            this.setRowCount(0);
            // 异常日志记录
        }
    }

    @Override
    public List<Expediente> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
        try {
            if (sortField == null || sortOrder.equals(SortOrder.UNSORTED)) {
                sortField = "id_expediente"; 
                sortOrder = SortOrder.DESCENDING;
            }

            this.dataSource = this.peticionesPendientes.buscarPendientesNativa(user.getCentroDirectivo().getCodCentro(),
                    user.getRole(), first, pageSize, sortField, sortOrder);
            
        } catch (final Exception e) {
            final FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(Cadenas.EVENT,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, Presentacion.ERROR_MSG, ERR.getString("error_con_motor")));
            dataSource = new ArrayList<Expediente>();
            this.setRowCount(dataSource.size());

            logger.log(Level.SEVERE, e.getMessage() + e.getCause(), e);
        }
        return dataSource;
    }
}

方案3:手动触发初始加载

在页面Bean的初始化方法中,手动调用load方法,确保rowCount被提前设置:

@ManagedBean
@ViewScoped
public class PeticionesPendientesBean {
    private LazyDataModel<Expediente> lazyModel;

    @PostConstruct
    public void init() {
        lazyModel = new CustomLazyModel(user, portaFirmaEnvios);
        // 手动触发初始加载,同步状态
        lazyModel.load(0, 10, null, SortOrder.UNSORTED, new HashMap<>());
    }
}

验证要点

  • 检查控制台输出的rowCount值,确认首次加载时总记录数已正确设置。
  • 验证buscarPendientesNativaCount方法返回的总记录数准确,无过滤条件错误。

内容的提问来源于stack exchange,提问作者Liliymas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:42:09