Справочная информация
Что такое компонент пользовательского интерфейса?
Ui Components используются для представления отдельных элементов пользовательского интерфейса, таких как таблицы, кнопки, формы и др. Это простые и гибкие компоненты, предназначенные для рендеринга пользовательского интерфейса, это компоненты, отвечающие за рендеринг фрагментов страницы и предоставляющие/поддерживающие дополнительные взаимодействия компонентов JavaScript.
Компоненты пользовательского интерфейса реализованы в модуле Magento_UI. Чтобы использовать Ui Components в пользовательском модуле, необходимо добавить зависимость для модуля Magento_UI в файл composer.json
модуля.
В Magento 2 основными компонентами пользовательского интерфейса являются формы и сетки списков, все остальные являются второстепенными. Основные компоненты объявляются в файлах макета страницы, а вторичные компоненты — в конфигурационных файлах экземпляров компонентов верхнего уровня.
Узнайте, как вставить ui_components в страницу в посте «Как создавать файлы макета Magento 2».
Объявления
Списки используются для представления, фильтрации и сортировки различных данных в бэкенде Magento, они также используются для выполнения массовых действий, таких как обновление, удаление, дублирование и другие действия.
Код для создания листинга
ui_component.xml
Файлы ui_components должны соответствовать структуре папок {Vendor}{Module}{area}{ui_components}{ui_component_name}.xml
.
Путь к области может быть frontend или adminhtml, что определяет, где будет применяться шаблон. Для вставки шаблона в админ-панель Magento используется область adminhtml, а для вставки шаблона в визуальную часть магазина — область frontend (в этой области он используется не очень часто).
<?xml version="1.0"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">{ui_component_name}.{ui_component_name}_data_source</item>
</item>
</argument>
<settings>
<buttons>
<button name="{button_name}">
<url path="{route_id}/{controller_folder_name}/{controller_name}"/>
<class>{class name}</class>
<label translate="true">{Button Label}</label>
</button>
</buttons>
<spinner>{columns_name}</spinner>
<deps>
<dep>{ui_component_name}.{ui_component_name}_data_source</dep>
</deps>
</settings>
<dataSource name="{ui_component_name}_data_source" component="Magento_Ui/js/grid/provider">
<settings>
<storageConfig>
<param name="indexField" xsi:type="string">{entity_id}</param>
</storageConfig>
<updateUrl path="mui/index/render"/>
</settings>
<aclResource>{Vendor}_{Module}::{parentResourceId}</aclResource>
<dataProvider class="{Vendor}{Module}UiDataProvider{EntityName}DataProvider" name="{ui_component_name}_data_source">
<settings>
<requestFieldName>{id}</requestFieldName>
<primaryFieldName>{entity_id}</primaryFieldName>
</settings>
</dataProvider>
</dataSource>
<listingToolbar name="listing_top">
<bookmark name="bookmarks"/>
<columnsControls name="columns_controls"/>
<filterSearch name="fulltext"/>
<filters name="listing_filters" />
<massaction name="listing_massaction" component="Magento_Ui/js/grid/tree-massactions">
<action name="{action_name}">
<settings>
<confirm>
<message translate="true">{Confirm message}</message>
<title translate="true">{Title message}</title>
</confirm>
<url path="{route_id}/{controller_folder_name}/{controller_name}"/>
<type>{type_name}</type>
<label translate="true">{Label}</label>
</settings>
</action>
<action name="{action_name}">
<settings>
<url path="{route_id}/{controller_folder_name}/{controller_name}"/>
<type>{type_name}</type>
<label translate="true">{Label}</label>
</settings>
</action>
</massaction>
<paging name="listing_paging"/>
<exportButton name="export_button"/>
</listingToolbar>
<columns name="{columns_name}">
<selectionsColumn name="ids" sortOrder="{integer}">
<settings>
<indexField>{entity_id}</indexField>
</settings>
</selectionsColumn>
<column name="{column_name}" sortOrder="{integer}">
<settings>
<filter>{filter_type}</filter>
<dataType>{data_type}</dataType>
<visible>{true/false}</visible>
<sorting>{asc/desc}</sorting>
<label translate="true">{Label}</label>
</settings>
</column>
<actionsColumn name="actions" class="{Vendor}{Module}UiComponent{ComponentName}ListingColumn{ActionName}" sortOrder="{integer}">
<settings>
<indexField>{entity_id}</indexField>
<label translate="true">{Label}</label>
</settings>
</actionsColumn>
</columns>
</listing>
Узел <listing>
является стандартным для компонентов пользовательского интерфейса Magento 2, где имя этого файла должно совпадать с именем атрибута name
, объявленного в узле <ui_component>
файла макета.
Аргумент
Узел <argument>
представляет собой произвольную структуру, которая объявляет конфигурацию компонента листинга, включающую данные, используемые для инициализации объекта. Дочерний узел <item name="provider">
отвечает за передачу данных в узел <dataSource>
. Значение этого элемента делится на две части (которые разделяет полная остановка), первое значение отвечает за указание имени компонента пользовательского интерфейса, а вторая часть отвечает за имя <dataSource>
, который предназначен для обработки данных на сервере и заставляет компонент пользовательского интерфейса обрабатывать эти данные.
Настройки
Узел <settings>
отвечает за настройку родительского узла <listing>
.
- Узел
<buttons>
: отвечает за добавление кнопок в верхнее меню листинга. Для каждой кнопки, которую вы хотите добавить, просто создайте дочерний узел<buttons>
и заполните атрибутname
для этого узла, который будет id этой кнопки. Чтобы настроить кнопку, просто создайте дочерние узлы (<label>
<url>
и<class>
). - Узел
<spinner>
: отвечает за скрытие изображения загрузки страницы при загрузке колонок, созданных в листинге; - Узел
<deps>
: должен иметь дочерний узел<dep>
и иметь такое же значение, как<item name="provider">
.
Источник данных
узел <dataSource>
ссылается на класс, который отвечает за получение запрошенных данных и взаимодействие с компонентом пользовательского интерфейса (многие компоненты *UI требуют этот узел для своей работы).
Атрибут component="Magento_Ui/js/grid/provider"
используется для поставщика данных для листинга в определенном формате, который является общим для всех компонентов пользовательского интерфейса в области действия компонента листинга. Рекомендуется назвать атрибут name="{ui_component_name}_data_source"
.
- Узел
<settings>
: отвечает за настройку родительского узла<dataSource>
и в нем вы можете определить, каким будет индексатор через узел<storageConfig>
, а узел<updateUrl>
отвечает за определение того, какой контроллер будет отвечать за обновление листинга; - Узел
<aclResource>
: определяет, к какому ресурсу ACL привязан и сможет ли вошедший в систему пользователь получить доступ на основе своей роли пользователя, каждый пользователь будет ограничен выбранными ресурсами своей роли; - Дочерний узел
<dataProvider>
: является классом, отвечающим за обработку данных, возвращаемых из Data Provider, на этот класс необходимо ссылаться через атрибутclass
и можно определить класс, отвечающий за это выполнение, который должен расширять класс<#Magento<##DataProvider
. Узел<dataProvider>
имеет дочерний узел<settings>
, где вы можете определить поле, которое будет использоваться в качестве id для грида в базе данных (через дочерний узел<primaryFieldName>
) и для запроса (через дочерний узел<requestFieldName>
);
Панель инструментов листинга
Узел <listingToolbar>
отвечает за определение массовых действий, фильтров, редактора колонок, поля поиска, экспорта и многих других функций, которые будут находиться в верхней части листинга.
- Узел
<bookmark>
: отвечает за предоставление функции, позволяющей сохранить состояние различных настроек листинга, связываясь с узлом<columnsControls>
. - Узел
<columnsControls>
: отвечает за добавление функциональности с колонками листинга, которая позволяет пользователю выбирать, какие колонки могут быть отображены в листинге. После изменения этого списка пользователь может сохранить это состояние через узел<bookmark>
, что позволяет ему быстро получить доступ к этому состоянию. - Узел
<filterSearch>
: этот узел отвечает за добавление поля поиска, в котором можно будет искать все поля в таблице, проиндексированные какfulltext
. - Узел
<filters>
: отвечает за отображение кнопки фильтрации, где вы устанавливаете поле фильтрации для каждого столбца в листинге. - Узел
<massaction>
: отвечает за добавление массового выбора действий в листинг, то есть с его помощью можно быстро выполнить действие над выбранными элементами из списка. - Узел
<paging>
: отвечает за добавление пагинации в листинг. - Узел
<exportButton>
: отвечает за добавление кнопки экспорта, с помощью которой можно экспортировать данные листинга.
Колонки
Узел <columns>
отвечает за отображение колонок в листинге и отключение спиннера при загрузке.
- Узел
<selectionsColumn>
: является компонентом, отвечающим за определение фильтра выбора, который позволяет пользователям выбрать все или отменить выбор всех элементов в листинге. - Узел
<column>
: отвечает за определение самого столбца. - Узел
<actionsColumn>
: отвечает за определение класса, который будет использоваться для кнопок действий для отдельного выбранного элемента.
Фильтры
Текст
Колонки со значением text
в узле <filter>
принимают строки для фильтрации по колонке.
<column name="{column_name}" sortOrder="{integer}">
<settings>
<filter>text</filter>
<dataType>text</dataType>
<label translate="true">{Label}</label>
</settings>
</column>
Диапазон текста
Колонки со значением textRange
в узле <filter>
принимают диапазон значений для фильтрации по колонке.
<column name="{column_name}" sortOrder="{integer}">
<settings>
<filter>textRange</filter>
<dataType>text</dataType>
<label translate="true">{Label}</label>
</settings>
</column>
Выберите
Колонки со значением select
в узле <filter>
принимают предопределенные параметры для фильтрации по колонке.
<column name="{column_name}" sortOrder="{integer}" component="Magento_Ui/js/grid/columns/select">
<settings>
<dataType>select</dataType>
<filter>select</filter>
<options>
<option name="{first_option_name}" xsi:type="array">
<item name="value" xsi:type="string">{first value}</item>
<item name="label" xsi:type="string" translate="true">{First Label}</item>
</option>
<option name="{second_option_name}" xsi:type="array">
<item name="value" xsi:type="string">{second value}</item>
<item name="label" xsi:type="string" translate="true">{Second Label}</item>
</option>
</options>
<label translate="true">{Label}</label>
</settings>
</column>
Диапазон дат
Колонки со значением dateRange
в узле <filter>
принимают диапазон дат для фильтрации по колонке.
<column name="{column_name}" class="MagentoUiComponentListingColumnsDate" component="Magento_Ui/js/grid/columns/date" sortOrder="{integer}">
<settings>
<dataType>date</dataType>
<filter>dateRange</filter>
<dateFormat>{format}</dateFormat>
<label translate="true">{Label}</label>
</settings>
</column>
Поставщик данных
Это класс PHP, отвечающий за предоставление данных из базы данных и обеспечение их доступности через атрибут name
. Класс
MagentoFrameworkViewElementUiComponentDataProviderCollectionFactory
отвечает за создание и возврат коллекции данных для листинга страницы. Для создания этой коллекции мы определяем значения конструктора с помощью инъекции зависимостей через узел <type>
. Узнайте, как создавать классы, использующие инжектируемые аргументы, с помощью файла di.xml
.
в посте "Как установить определенные значения аргументов конструктора в Magento 2, используя тип".
<type name="MagentoFrameworkViewElementUiComponentDataProviderCollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="{ui_component}_data_source" xsi:type="string">{Vendor}{Module}ModelResourceModel{EntityName}Grid{CollectionName}</item>
</argument>
</arguments>
</type>
Результат поиска
Список результатов включает все элементы, соответствующие критериям поиска коллекции. Результаты могут быть оформлены в виде списка и отсортированы по ряду признаков.
Результаты поиска коллекции списков можно создать несколькими способами (виртуальные типы, типы или путем создания класса PHP). В любом случае необходимо передать имя таблицы и модель ресурса сущности, используемой в листинге.
Виртуальный тип
О том, как создавать виртуальные классы, использующие инжектируемые аргументы, с помощью файла di.xml
, читайте в посте "Как использовать виртуальные типы в Magento 2".
<virtualType name="{Vendor}{Module}ModelResourceModel{EntityName}GridCollection" type="MagentoFrameworkViewElementUiComponentDataProviderSearchResult">
<arguments>
<argument name="mainTable" xsi:type="string">{table_name}</argument>
<argument name="resourceModel" xsi:type="string">{Vendor}{Module}ModelResourceModel{ResourceModelName}</argument>
</arguments>
</virtualType>
Тип
<type name="{Vendor}{Module}ModelResourceModel{EntityName}Grid{CollectionName}">
<arguments>
<argument name="mainTable" xsi:type="string">{table_name}</argument>
<argument name="resourceModel" xsi:type="string">{Vendor}{Module}ModelResourceModel{ResourceModelName}</argument>
</arguments>
</type>
Класс PHP
Если вы хотите создать класс PHP, вам нужно расширить класс, который имеет реализацию интерфейса
и установить значения в конструкторе.
<?php
namespace {Vendor}{Module}ModelResourceModel{EntityName}Grid;
use MagentoFrameworkViewElementUiComponentDataProviderSearchResult;
use MagentoFrameworkDataCollectionEntityFactoryInterface as EntityFactory;
use PsrLogLoggerInterface as Logger;
use MagentoFrameworkDataCollectionDbFetchStrategyInterface as FetchStrategy;
use MagentoFrameworkEventManagerInterface as EventManager;
use {Vendor}{Module}ModelResourceModel{EntityName} as {ResourceModelName};
class {CollectionName} extends SearchResult
{
protected array $_map = [
'fields' => [
'entity_id' => 'main_table.entity_id'
]
];
public function __construct(
EntityFactory $entityFactory,
Logger $logger,
FetchStrategy $fetchStrategy,
EventManager $eventManager,
string $mainTable = '{table_name}',
string $resourceModel = {ResourceModelName}::class
) {
parent::__construct(
$entityFactory,
$logger,
$fetchStrategy,
$eventManager,
$mainTable,
$resourceModel
);
}
}
Действия в колонне
Этот класс отвечает за возврат действий, которые будут воздействовать на выбранный элемент, для этого класс должен расширить класс
MagentoUiComponentListingColumns
и реализовать метод prepareDataSource(array $dataSource): array
, возвращая переменную $dataSource
, отредактированную по желанию.
<?php
namespace {Vendor}{Module}UiComponent{EntityName};
use MagentoUiComponentListingColumnsColumn;
use MagentoFrameworkViewElementUiComponentContextInterface;
use MagentoFrameworkViewElementUiComponentFactory;
class Action extends Column
{
protected const HREF_EDIT = '{route_id}/{controller_folder}/{controller_edit_name}';
protected const HREF_DELETE = '{route_id}/{controller_folder}/{controller_delete_name}';
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
array $components = [],
array $data = []
) {
parent::__construct(
$context,
$uiComponentFactory,
$components,
$data
);
}
public function prepareDataSource(array $dataSource): array
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as &$item) {
$item[$this->getData('name')]['edit'] = [
'href' => $this->context->getUrl(self::HREF_EDIT, ['id' => $item['entity_id']]),
'label' => __('Edit')
];
$item[$this->getData('name')]['delete'] = [
'href' => $this->context->getUrl(self::HREF_DELETE, ['id' => $item['entity_id']]),
'label' => __('Delete')
];
}
}
return $dataSource;
}
}
Отделка
🔗 Значения, заключенные в скобки ({test}
), должны быть изменены в реализации кода.
Включение изменений
Выполните команду PHP, чтобы очистить все кэши процессов.
rm -rf var/generation/
rm -rf generated/
php bin/magento setup:di:compile
php bin/magento cache:clean
php bin/magento flush
Каталоги и файлы
Вот список каталогов и файлов, которые должны быть созданы.
- app/
- code/
- {Vendor}/
- {Module}/
- etc/
- di.xml
- module.xml
- Ui/
- Component/
- {EntityName}/
- Action.php
- view/
- adminhtml/
- layout/
- {router_id}_{controller_directory}_{controller_name}.xml
- ui_component/
- {ui_component}.xml
- registration.php
- composer.json