Magento 2.4.3获取筛选列表输出价格区间报错解决方案
- 运行环境:Magento 2.4.3
- 需求:获取筛选器列表,在自定义
TopMenu.php板块中输出价格区间列表,参考效果:
原有代码与报错
最初尝试直接实例化FilterList类获取筛选列表,代码如下:
$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $stateFilter = $objectManager->create('\Magento\Catalog\Model\Layer\FilterList'); $selectedFilters = $stateFilter->getFilters(); foreach($selectedFilters as $filter){ $html .= $filter->getName(); $html .= $filter->getLabel(); }
运行后抛出错误:
Cannot instantiate interface Magento\Catalog\Model\Layer\FilterableAttributeListInterface
错误原因
Magento\Catalog\Model\Layer\FilterList构造函数依赖FilterableAttributeListInterface接口,直接通过create方法实例化时未传入对应实现类参数;同时Magento分层筛选依赖当前页面对应的Layer上下文(分类页、搜索页Layer实例不通用),全局直接实例化无法获取正确的筛选数据。
正确实现步骤
1. 按规范通过依赖注入引入相关类
禁止直接调用ObjectManager,在自定义TopMenu.php的构造函数中注入所需依赖:
<?php namespace 你的自定义模块对应命名空间; use Magento\Catalog\Model\Layer\Resolver as LayerResolver; use Magento\Catalog\Model\Layer\FilterList; use Magento\Catalog\Model\Layer\Category\FilterableAttributeList; class TopMenu { protected $layerResolver; protected $filterList; public function __construct( LayerResolver $layerResolver, FilterableAttributeList $filterableAttributeList, // 保留类文件中原有的其他依赖参数 ) { $this->layerResolver = $layerResolver; // 传入分类页对应的可筛选属性实现、当前Layer实例初始化FilterList $this->filterList = new FilterList($filterableAttributeList, $layerResolver->get()); // 保留原构造函数中的其他逻辑 } }
2. 提取筛选器输出价格区间
在需要输出筛选内容的方法中加入以下逻辑:
// 获取当前分层下的全部筛选器 $filters = $this->filterList->getFilters($this->layerResolver->get()); $html = ''; foreach ($filters as $filter) { // 匹配价格筛选器 if ($filter->getRequestVar() === 'price') { $priceItems = $filter->getItems(); $html .= '<div class="price-filter-block">'; $html .= '<h4>' . $filter->getName() . '</h4>'; $html .= '<ul class="price-range-list">'; foreach ($priceItems as $rangeItem) { $html .= '<li>'; $html .= '<a href="' . $rangeItem->getUrl() . '">' . $rangeItem->getLabel() . '</a>'; $html .= '</li>'; } $html .= '</ul>'; $html .= '</div>'; } // 需要输出其他属性筛选器时,取消下方注释即可 /* $html .= '<div class="common-filter-block">'; $html .= '<h4>' . $filter->getName() . '</h4>'; $html .= '<ul>'; foreach ($filter->getItems() as $item) { $html .= '<li><a href="'.$item->getUrl().'">'.$item->getLabel().'</a></li>'; } $html .= '</ul></div>'; */ } return $html;
注意事项
- 如果逻辑运行在搜索页面,需要将构造函数中注入的
Magento\Catalog\Model\Layer\Category\FilterableAttributeList替换为搜索场景的实现类Magento\CatalogSearch\Model\Layer\Search\FilterableAttributeList,否则无法正常获取搜索页筛选结果 - 代码上传后执行
bin/magento cache:clean清理缓存,避免依赖注入编译缓存导致类加载异常 - 非特殊场景不要直接使用ObjectManager实例化类,会导致代码耦合度高、版本兼容性差,不符合Magento2开发规范
内容的提问来源于stack exchange,提问作者MarioProject
相关产品推荐
相关产品推荐

