
本文详解如何在 magento 2 自定义模块页面(如报价单列表页)中正确集成原生分页器,涵盖 collection 分页配置、block 中 pager 实例化、模板调用及关键注意事项,确保每页显示指定数量记录并支持页码跳转。
本文详解如何在 magento 2 自定义模块页面(如报价单列表页)中正确集成原生分页器,涵盖 collection 分页配置、block 中 pager 实例化、模板调用及关键注意事项,确保每页显示指定数量记录并支持页码跳转。
在 Magento 2 中为自定义页面(例如客户报价单列表页)添加分页,不能仅依赖前端渲染或手动切片数据——必须结合 EAV Collection 的分页机制与框架内置的 Magento\Theme\Block\Html\Pager 组件协同工作。以下是一个经过生产环境验证的完整实现方案。
✅ 核心步骤概览
- 在 Block 类中重写 _prepareLayout(),动态创建并绑定 Pager 实例;
- 确保 getSavedQuotes() 方法返回已配置分页参数(setPageSize + setCurPage)的 Collection;
- 在 .phtml 模板中调用 = $block->getPagerHtml() ?> 渲染分页控件;
- 注意请求参数解析、Collection 加载时机及模板输出位置。
? Block 层实现(推荐继承 \Magento\Framework\View\Element\Template)
<?php
namespace Vendor\Module\Block;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Customer\Model\Session as CustomerSession;
class QuoteList extends Template
{
protected $customerSession;
protected $_quoteMainFactory;
public function __construct(
Context $context,
CustomerSession $customerSession,
\Vendor\Module\Model\QuoteFactory $quoteMainFactory,
array $data = []
) {
$this->customerSession = $customerSession;
$this->_quoteMainFactory = $quoteMainFactory;
parent::__construct($context, $data);
}
protected function _prepareLayout()
{
parent::_prepareLayout();
$this->pageConfig->getTitle()->set(__('My Quotes'));
$collection = $this->getSavedQuotes();
if ($collection && $collection->getSize()) {
$pager = $this->getLayout()->createBlock(
\Magento\Theme\Block\Html\Pager::class,
'quotes.pager'
)
->setAvailableLimit([10 => 10, 20 => 20, 30 => 30])
->setShowPerPage(true) // 启用「每页显示」下拉框(设为 false 则隐藏)
->setCollection($collection);
$this->setChild('pager', $pager);
// ⚠️ 关键:必须显式调用 load(),否则 pager 无法获取总条数
$collection->load();
}
return $this;
}
public function getPagerHtml()
{
return $this->getChildHtml('pager');
}
public function getSavedQuotes()
{
$page = (int)$this->getRequest()->getParam('p', 1);
$pageSize = (int)$this->getRequest()->getParam('limit', 10);
$collection = $this->_quoteMainFactory->create()->getCollection()
->addFieldToFilter('is_deleted', 0)
->addFieldToFilter('status', 1)
->addFieldToFilter('customer_id', $this->customerSession->getCustomer()->getId());
// 必须在 load() 前设置分页参数
return $collection->setPageSize($pageSize)->setCurPage($page);
}
}? 对应 PHTML 模板(如 quote/list.phtml)
在循环展示数据的下方,插入分页 HTML:
<!-- 显示报价列表 -->
<?php foreach ($block->getSavedQuotes() as $quote): ?>
<div class="quote-item">
<h3><?= $block->escapeHtml($quote->getName()) ?></h3>
<p>Status: <?= $block->escapeHtml($quote->getStatus()) ?></p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/code/10660" title="标准小型企业网站"><img
src="https://img.php.cn/upload/webcode/000/000/015/176318640731664.png" alt="标准小型企业网站" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/code/10660" title="标准小型企业网站">标准小型企业网站</a>
<p>包括完整的产品展示,精美留言本,经理致辞,公司简介,联系我们等,其中本系统的产品展示可以实现三级分类,无限产品后台自由添加。包含产品快速导航,产品简介,下订单,产品成分说明,常见问题说明,大小缩略图等非常实用的功能 产品管理页面:/HBYYDS/product/admin/login.asp 管理帐号及密码均为admin</p>
</div>
<a href="/xiazai/code/10660" title="标准小型企业网站" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div>
</div>
<?php endforeach; ?>
<!-- 分页控件(务必放在循环之后) -->
<div class="toolbar toolbar-bottom">
<?= $block->getPagerHtml() ?>
</div>⚠️ 关键注意事项
- load() 调用时机:$collection->load() 必须在 setCollection($collection) 后、$this->setChild() 前执行,否则 Pager 无法读取 getTotalCount();
- 参数命名规范:Magento 默认识别 p(当前页)和 limit(每页条数),勿自定义为 page/size,否则需重写 Pager 的 getPageRouteParams();
- Collection 复用风险:getSavedQuotes() 被多次调用时,避免重复 load();建议加缓存或使用 clone 避免状态污染;
- 响应式适配:如需移动端优化,可在 CSS 中调整 .pages, .limiter 等 pager 默认类;
- SEO 友好性:分页链接自动包含 canonical 标签,无需额外处理。
✅ 验证方式
访问页面后检查 URL 是否支持如下格式:
- yourdomain.com/quotes/?p=2 → 第二页
- yourdomain.com/quotes/?p=1&limit=20 → 每页 20 条,第一页
同时查看 HTML 源码,确认









