使用 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在本系列的下一篇文章中,我們將描述添加質量的可能性——動作和額外的列。
敬請關注!