Как создать список/листинг администратора Magento 2


Справочная информация

Что такое компонент пользовательского интерфейса?

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, вам нужно расширить класс, который имеет реализацию интерфейса ApiSearchSearchResultInterface и установить значения в конструкторе.

<?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
Войдите в полноэкранный режим Выход из полноэкранного режима

Оцените статью
Procodings.ru
Добавить комментарий