使用 UI 组件升级标准 Magento 2 网格(第 2 部分)
已发表: 2016-10-18在上一篇文章中,我们已经描述了如何创建一个具有基本条件的模块以及让我们使用它们的接口。 在创建过程中,我们使用了标准的 Magento 块。 但是,Magento 2 能够做的更多。
我说的是在 UI 组件的帮助下改进界面的可能性。 这些组件是通过 Magento/UI 模块添加的。
*虽然这些组件可以在 v.2.0 中找到,但我们强烈建议您使用 2.1 版本。
从本文中,您将了解如何重新制作标准网格(位于布局中: app/code/Vendor/Rules/view/adminhtml/layout/vendor_rules_example_rule_index.xml )并使用 UI 组件丰富它。
只是比较。 这是一个旧网格:

使用 UX 组件制作的新产品:

如您所见,升级后的 Grid 将更加用户友好和省时,更易于扩展,具有许多出色的额外功能(例如能够保存当前 Grid 状态的书签)和设置智能过滤器。
那么,让我们开始吧。
首先,您需要对模块进行一些更改。 下面是如何做到这一点:
1)创建一个新文件来声明必要的组件:
> 应用程序/代码/供应商/规则/etc/di.xml
<?xml 版本="1.0"?>
<config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<virtualType name="VendorRulesRuleGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
<参数>
<argument name="collection" xsi:type="object" shared="false">Vendor\Rules\Model\ResourceModel\Rule\Collection</argument>
<argument name="filterPool" xsi:type="object" shared="false">VendorRulesRuleGridFilterPool</argument>
</参数>
</virtualType>
<virtualType name="VendorRulesRuleGridFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
<参数>
<argument name="appliers" xsi:type="array">
<item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
<item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
</参数>
</参数>
</virtualType>
<type name="供应商\Rules\Model\ResourceModel\Rule\Grid\Collection">
<参数>
<argument name="mainTable" xsi:type="string">vendor_rules</argument>
<argument name="eventPrefix" xsi:type="string">vendor_rules_rule_grid_collection</argument>
<argument name="eventObject" xsi:type="string">rule_grid_collection</argument>
<argument name="resourceModel" xsi:type="string">Vendor\Rules\Model\ResourceModel\Rule</argument>
</参数>
</类型>
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<参数>
<argument name="collections" xsi:type="array">
<item name="vendor_rules_rule_listing_data_source" xsi:type="string">Vendor\Rules\Model\ResourceModel\Rule\Grid\Collection</item>
</参数>
</参数>
</类型>
</配置>
VendorRulesRuleGridDataProvide — 此虚拟类型为 UI 规则网格提供数据。 VendorRulesRuleGridFilterPool反过来添加了过滤功能,允许您添加/修改任何现有的过滤器。
请注意,要使 Grid 与此特定集合正常工作,您需要将其添加到所有可用集合的列表中。 为此,请将vendor_rules_rule_listing_data_source与基于集合值的类: Vendor\Rules\Model\ResourceModel\Rule\Grid\Collection 添加到 Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory 集合中。
2) 对于 UI Grid,我们需要一个单独的集合来表示“Magento\Framework\Api\Search\SearchResultInterface”接口。
它包含允许您使用网格和过滤器的标准方法。 通过更改按集合搜索的工作方式,可以根据您的个人需求定制此类。
> app/code/Vendor/Rules/Model/ResourceModel/Rule/Grid/Collection.php
<?php
命名空间供应商\规则\模型\资源模型\规则\网格;
使用 Vendor\Rules\Model\ResourceModel\Rule\Collection 作为 RuleCollection;
使用 Magento\Framework\Api\Search\SearchResultInterface;
使用 Magento\Framework\Api\SearchCriteriaInterface;
使用 Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
使用 Magento\Framework\Data\Collection\EntityFactory;
使用 Magento\Framework\Event\ManagerInterface;
使用 Magento\Framework\Model\ResourceModel\Db\AbstractDb;
使用 Psr\Log\LoggerInterface;
类 Collection 扩展 RuleCollection 实现 SearchResultInterface
{
/**
* 聚合
*
* @var \Magento\Framework\Search\AggregationInterface
*/
受保护的$聚合;
/**
* 构造函数
*
* @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param $mainTable
* @param $eventPrefix
* @param $eventObject
* @param $resourceModel
* @param $模型
* @param $连接
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource
*/
公共函数 __construct(
实体工厂$实体工厂,
记录器接口 $logger,
FetchStrategyInterface $fetchStrategy,
ManagerInterface $eventManager,
$主表,
$事件前缀,
$事件对象,
$资源模型,
$model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
$连接=空,
抽象数据库 $resource = null
) {
父::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
$this->_eventPrefix = $eventPrefix;
$this->_eventObject = $eventObject;
$this->_init($model, $resourceModel);
$this->setMainTable($mainTable);
}
/**
* @return \Magento\Framework\Search\AggregationInterface
*/
公共函数 getAggregations()
{
返回 $this-> 聚合;
}
/**
* @param \Magento\Framework\Search\AggregationInterface $aggregations
* @return $this
*/
公共函数 setAggregations($aggregations)
{
$this->aggregations = $aggregations;
}
/**
* 检索所有 id 以供收集
* 向后兼容 EAV 集合
*
* @param int $limit
* @param int $offset
* @return 数组
*/
公共函数 getAllIds($limit = null, $offset = null)
{
返回 $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams);
}
/**
* 获取搜索条件。
*
* @return \Magento\Framework\Api\SearchCriteriaInterface|null
*/
公共函数 getSearchCriteria()
{
返回空值;
}
/**
* 设置搜索条件。
*
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
公共函数 setSearchCriteria(SearchCriteriaInterface $searchCriteria = null)
{
返回$这个;
}
/**
* 获取总数。
*
* @return 整数
*/
公共函数 getTotalCount()
{
返回 $this->getSize();
}
/**
* 设置总计数。
*
* @param int $totalCount
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
公共函数 setTotalCount($totalCount)
{
返回$这个;
}
/**
*设置项目列表。
*
* @param \Magento\Framework\Api\ExtensibleDataInterface[] $items
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
公共函数 setItems(数组 $items = null)
{
返回$这个;
}
}
?>3)按照下面描述的方式修改主集合(这很重要,因为我们的自定义集合是从它继承的)。 您应该进行以下更改:
> app/code/Vendor/Rules/Model/ResourceModel/Rule/Collection.php
<?php
命名空间供应商\规则\模型\资源模型\规则;
类集合扩展 \Magento\Rule\Model\ResourceModel\Rule\Collection\AbstractCollection
{
/**
* 设置资源模型并确定字段映射
*
* @return 无效
*/
受保护的函数 _construct()
{
$this->_init('Vendor\Rules\Model\Rule', 'Vendor\Rules\Model\ResourceModel\Rule');
}
/**
*按指定日期过滤收藏。
* 将集合过滤到仅活动规则。
*
* @param string|null $now
* @use $this->addStoreGroupDateFilter()
* @return $this
*/
公共函数 setValidationFilter($now = null)
{
if (!$this->getFlag('validation_filter')) {
$this->addDateFilter($now);
$this->addIsActiveFilter();
$this->setOrder('sort_order', self::SORT_ORDER_DESC);
$this->setFlag('validation_filter', true);
}
返回$这个;
}
/**
* 从日期或到日期过滤器
*
* @param $now
* @return $this
*/
公共函数 addDateFilter($now)
{
$this->getSelect()->where(
'from_date 为 null 或 from_date <= ?',
$现在
)->哪里(
'to_date 为 null 或 to_date >= ?',
$现在
);
返回$这个;
}
}
?>
4) 接下来,从 Grid 布局中删除旧标记并在那里添加一个 UI 列表:
> 应用程序/代码/供应商/规则/视图/adminhtml/layout/vendor_rules_example_rule_index.xml
<?xml 版本="1.0"?>
<page xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<正文>
<referenceBlock name="menu">
<action method="setActive">
<argument name="itemId" xsi:type="string">Vendor_Rules::vendor_rules</argument>
</行动>
</参考块>
<referenceBlock name="page.title">
<action method="setTitleClass">
<argument name="class" xsi:type="string">复杂</argument>
</行动>
</参考块>
<referenceContainer 名称="内容">
<uiComponent name="vendor_rules_rule_listing"/>
</referenceContainer>
</正文>
</页面>基本上,我们只需将提到的` vendor_rules_rule_listing`添加到页面内容(主要操作)中,将我们的产品菜单的状态更改为“活动”,并设置标题类。
5) 在下一步中,我们创建 UI 列表,将其放置在这里:
> 应用程序/代码/供应商/规则/视图/adminhtml/ui_component/vendor_rules_rule_listing.xml
<?xml 版本="1.0"?>
<listing xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Ui/etc/ui_configuration.xsd">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing_data_source</item>
<item name="deps" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing_data_source</item>
</项目>
<item name="spinner" xsi:type="string">vendor_rules_rule_columns</item>
<item name="buttons" xsi:type="array">
<item name="add" xsi:type="array">
<item name="name" xsi:type="string">添加</item>
<item name="label" xsi:type="string" translate="true">添加新规则</item>
<item name="class" xsi:type="string">主要</item>
<item name="url" xsi:type="string">*/*/newaction</item>
</项目>
</项目>
</参数>
<dataSource name="vendor_rules_rule_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">VendorRulesRuleGridDataProvider</argument>
<argument name="name" xsi:type="string">vendor_rules_rule_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">rule_id</argument>
<argument name="requestFieldName" xsi:type="string">rule_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="update_url" xsi:type="url" path="mui/index/render"/>
</项目>
</参数>
</参数>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
</项目>
</参数>
</数据源>
<容器名称="listing_top">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">ui/grid/toolbar</item>
<item name="stickyTmpl" xsi:type="string">ui/grid/sticky/toolbar</item>
</项目>
</参数>
<书签名称="书签">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="namespace" xsi:type="string">vendor_rules_rule_listing</item>
</项目>
</项目>
</参数>
</书签>
<组件名称="columns_controls">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsData" xsi:type="array">
<item name="provider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.vendor_rules_rule_columns</item>
</项目>
<item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
<item name="displayArea" xsi:type="string">dataGridActions</item>
</项目>
</参数>
</组件>
<过滤器名称="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsProvider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.vendor_rules_rule_columns</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.filters</item>
</项目>
<item name="模板" xsi:type="array">
<item name="filters" xsi:type="array">
<item name="select" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
<item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
</项目>
</项目>
</项目>
<item name="childDefaults" xsi:type="array">
<item name="provider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.listing_top.listing_filters</item>
<item name="imports" xsi:type="array">
<item name="visible" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.vendor_rules_rule_columns.${ $.index }:visible</item>
</项目>
</项目>
</项目>
<item name="observers" xsi:type="array">
<item name="column" xsi:type="string">column</item>
</项目>
</参数>
</过滤器>
<分页名称="listing_paging">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.paging</item>
</项目>
<item name="selectProvider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.vendor_rules_rule_columns.ids</item>
</项目>
</参数>
</paging>
</容器>
<columns name="vendor_rules_rule_columns">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">当前</item>
</项目>
</项目>
</参数>
<selectionsColumn name="ids">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="resizeEnabled" xsi:type="boolean">false</item>
<item name="resizeDefaultWidth" xsi:type="string">55</item>
<item name="indexField" xsi:type="string">rule_id</item>
</项目>
</参数>
</selectionsColumn>
<column name="rule_id">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
</项目>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">textRange</item>
<item name="dataType" xsi:type="string">文本</item>
<item name="sorting" xsi:type="string">asc</item>
<item name="align" xsi:type="string">left</item>
<item name="label" xsi:type="string" translate="true">ID</item>
<item name="sortOrder" xsi:type="number">1</item>
</项目>
</参数>
</列>
<列名=“名称”>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
</项目>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">文本</item>
<item name="dataType" xsi:type="string">文本</item>
<item name="align" xsi:type="string">left</item>
<item name="label" xsi:type="string" translate="true">名称</item>
</项目>
</参数>
</列>
<列名="is_active">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="array">
<item name="active" xsi:type="array">
<item name="value" xsi:type="string">1</item>
<item name="label" xsi:type="string" translate="true">活动</item>
</项目>
<item name="inactive" xsi:type="array">
<item name="value" xsi:type="string">0</item>
<item name="label" xsi:type="string" translate="true">无效</item>
</项目>
</项目>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">选择</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
<item name="editor" xsi:type="string">选择</item>
<item name="dataType" xsi:type="string">选择</item>
<item name="label" xsi:type="string" translate="true">已激活</item>
<item name="sortOrder" xsi:type="number">65</item>
</项目>
</参数>
</列>
<列名=“排序顺序”>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
</项目>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">文本</item>
<item name="dataType" xsi:type="string">数字</item>
<item name="align" xsi:type="string">left</item>
<item name="label" xsi:type="string" translate="true">优先级</item>
</项目>
</参数>
</列>
<column name="from_date" class="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sorting" xsi:type="string">desc</item>
<item name="filter" xsi:type="string">dateRange</item>
<item name="dataType" xsi:type="string">日期</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
<item name="label" xsi:type="string" translate="true">开始</item>
</项目>
</参数>
</列>
<column name="to_date" class="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sorting" xsi:type="string">desc</item>
<item name="filter" xsi:type="string">dateRange</item>
<item name="dataType" xsi:type="string">日期</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
<item name="label" xsi:type="string" translate="true">结束</item>
</项目>
</参数>
</列>
<actionsColumn name="actions" class="供应商\Rules\Ui\Component\Listing\Column\RuleActions">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="indexField" xsi:type="string">rule_id</item>
<item name="urlEntityParamName" xsi:type="string">rule_id</item>
<item name="sortOrder" xsi:type="number">70</item>
</项目>
</参数>
</actionsColumn>
</列>
<容器名称="粘性">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/sticky/sticky</item>
<item name="toolbarProvider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.listing_top</item>
<item name="listingProvider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.vendor_rules_rule_columns</item>
</项目>
</参数>
</容器>
</listing>
清单 ` dataSource`包含指向` dataProvider`的链接——我们在` di.xml`中创建的类型。 它包含网格所需的输入数据。

从这里开始,我们需要定义密钥字段——在我们的例子中是 ` rule_id` 。
此外,您还可以添加自定义按钮,只需在“按钮”部分进行描述。 在我们的示例中,我们添加了标准的“添加”按钮,地址为 ` */*/newaction `(路径中的 * 对应于当前含义)。
` container name="listing_top" ` 包含一些额外的列表组件:过滤器、分页等。 您可以根据您的个人要求更改它们。
` columns name=“vendor_rules_rule_columns” ` 包含与默认网格几乎相同的列。 唯一有意义的区别是一个新的 ` actionsColumn`列,它引入了一组操作:编辑和删除。 如果需要,这些操作也可以扩展。
您可能已经注意到,本专栏有一个新类。 让我们学习如何创建它:
> app/code/Vendor/Rules/Ui/Component/Listing/Column/RuleActions.php
<?php
命名空间供应商\Rules\Ui\Component\Listing\Column;
类 RuleActions 扩展 \Magento\Ui\Component\Listing\Columns\Column
{
/**
* 要编辑的网址路径
*
* @var 字符串
*/
const URL_PATH_EDIT = 'vendor_rules/example_rule/edit';
/**
* 要删除的url路径
*
* @var 字符串
*/
const URL_PATH_DELETE = 'vendor_rules/example_rule/delete';
/**
* 网址生成器
*
* @var \Magento\Framework\UrlInterface
*/
受保护的 $urlBuilder;
/**
* 构造函数
*
* @param \Magento\Framework\UrlInterface $urlBuilder
* @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
* @param \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory
* @param 数组 $components
* @param 数组 $data
*/
公共函数 __construct(
\Magento\Framework\UrlInterface $urlBuilder,
\Magento\Framework\View\Element\UiComponent\ContextInterface $context,
\Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory,
数组 $components = [],
数组 $data = []
) {
$this->urlBuilder = $urlBuilder;
父::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* 准备数据源
*
* @param 数组 $dataSource
* @return 数组
*/
公共函数prepareDataSource(数组$dataSource)
{
if (!isset($dataSource['data']['items'])) {
返回$数据源;
}
foreach ($dataSource['data']['items'] as &$item) {
if (!isset($item['rule_id'])) {
继续;
}
$item[$this->getData('name')] = [
'编辑' => [
'href' => $this->urlBuilder->getUrl(
静态::URL_PATH_EDIT,
[
'id' => $item['rule_id'],
]
),
'标签' => __('编辑'),
],
'删除' => [
'href' => $this->urlBuilder->getUrl(
静态::URL_PATH_DELETE,
[
'id' => $item['rule_id'],
]
),
'标签' => __('删除'),
'确认' => [
'title' => __('删除 "${ $.$data.name }"'),
'message' => __('Are you sure you want to delete the rule "${ $.$data.name }" ?'),
],
],
];
}
返回$数据源;
}
}
?>这个类负责处理来自网格的动作。 从这里,可以更改 URL 或传输参数的名称。 在我们的例子中,key 是 rule_id(它以名称 'id' 传输,以便于理解它的值)。
它看起来像这样:

如果您以正确的方式完成了所有操作,您的网格应该如下所示:

从示例中我们可以看出,将现有的标准 Grid 转换为 UI 非常容易。 除了扩展标准 Grid 功能外,它还允许您简化 Magento 2 功能的这一部分的使用。
PS在本系列的下一篇文章中,我们将描述添加质量的可能性——动作和额外的列。
敬请关注!
