Actualizarea rețelei standard Magento 2 cu componente UI (Partea 2)
Publicat: 2016-10-18În articolul anterior, am descris cum să creăm un modul cu condițiile de bază și interfața care ne va permite să lucrăm cu ele. În timpul procesului de creare am folosit blocurile standard Magento. Cu toate acestea, Magento 2 este capabil să facă mult mai mult.
Vorbesc despre posibilitatea de a îmbunătăți interfața cu ajutorul componentelor UI. Aceste componente sunt adăugate cu modulul Magento/UI.
*deși aceste componente pot fi găsite în v.2.0, vă recomandăm insistent să utilizați versiunea 2.1.
Din acest articol, veți învăța cum să refaceți grila standard (aflată în aspectul: app/code/Vendor/Rules/view/adminhtml/layout/vendor_rules_example_rule_index.xml ) și să o îmbogățiți cu componente UI.
Doar compara. Aceasta este o grilă veche:
cu unul nou, realizat cu componente UX:
După cum puteți vedea, o rețea actualizată va fi mult mai ușor de utilizat și va economisi timp, mai ușor de scalat, va avea o mulțime de caracteristici suplimentare grozave (de exemplu, marcaje care sunt capabile să salveze starea actuală a rețelei) și să seteze filtre inteligente.
Asadar, hai sa incepem.
În primul rând, trebuie să faceți câteva modificări în modul. Mai jos este cum să faci asta:
1) Creați un fișier nou pentru a declara componentele necesare:
> app/code/Vendor/Rules/etc/di.xml
<?xml version="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"> <argumente> <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> </argumente> </virtualType> <virtualType name="VendorRulesRuleGridFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool"> <argumente> <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> </argument> </argumente> </virtualType> <type name="Vendor\Rules\Model\ResourceModel\Rule\Grid\Collection"> <argumente> <argument name="mainTable" xsi:type="string">reguli_furnizor</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">Vânzător\Reguli\Model\ResourceModel\Regulă</argument> </argumente> </tip> <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory"> <argumente> <argument name="colecții" xsi:type="array"> <item name="vendor_rules_rule_listing_data_source" xsi:type="string">Vendor\Rules\Model\ResourceModel\Rule\Grid\Collection</item> </argument> </argumente> </tip> </config>
VendorRulesRuleGridDataProvide — acest tip virtual oferă date pentru grila de reguli UI. VendorRulesRuleGridFilterPool , la rândul său, adaugă funcționalitate de filtrare care vă permite să adăugați/modificați orice filtre existente.
Rețineți, pentru ca Grila să funcționeze corect cu această colecție specială, trebuie să o adăugați la lista tuturor colecțiilor disponibile. Pentru a face asta, adăugați vendor_rules_rule_listing_data_source cu clasa de colecție bazată pe valoare: Vendor\Rules\Model\ResourceModel\Rule\Grid\Collection în colecțiile Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory.
2) Pentru UI Grid, avem nevoie de o colecție separată care va reprezenta interfața `Magento\Framework\Api\Search\SearchResultInterface` .
Conține metodele standard care vă vor permite să lucrați cu Grid și filtre. Această clasă poate fi personalizată în funcție de nevoile dumneavoastră personale, schimbând modul în care funcționează căutarea după colecții .
> app/code/Vendor/Rules/Model/ResourceModel/Rule/Grid/Collection.php
<?php spațiu de nume Vendor\Rules\Model\ResourceModel\Rule\Grid; utilizați Vendor\Rules\Model\ResourceModel\Rule\Collection ca RuleCollection; utilizați Magento\Framework\Api\Search\SearchResultInterface; utilizați Magento\Framework\Api\SearchCriteriaInterface; utilizați Magento\Framework\Data\Collection\Db\FetchStrategyInterface; utilizați Magento\Framework\Data\Collection\EntityFactory; utilizați Magento\Framework\Event\ManagerInterface; utilizați Magento\Framework\Model\ResourceModel\Db\AbstractDb; utilizați Psr\Log\LoggerInterface; Class Collection extinde RuleCollection implementează SearchResultInterface { /** * Agregații * * @var \Magento\Framework\Search\AggregationInterface */ $agregatii protejate; /** * constructor * * @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 $model * @param $conexiune * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource */ funcția publică __construct( EntityFactory $entityFactory, LoggerInterface $logger, FetchStrategyInterface $fetchStrategy, ManagerInterface $eventManager, $mainTable, $eventPrefix, $eventObject, $resourceModel, $model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document', $conexiune = nul, AbstractDb $resursa = null ) { parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $conexiune, $resursa); $this->_eventPrefix = $eventPrefix; $this->_eventObject = $eventObject; $this->_init($model, $resourceModel); $this->setMainTable($mainTable); } /** * @return \Magento\Framework\Search\AggregationInterface */ funcția publică getAggregations() { returnează $this->agregations; } /** * @param \Magento\Framework\Search\AggregationInterface $agregații * @return $this */ funcția publică setAggregations($agregații) { $this->agregations = $agregations; } /** * Preluați toate ID-urile pentru colectare * Compatibilitate cu colecția EAV * * @param int $limit * @param int $offset * @return matrice */ funcția publică getAllIds($limit = null, $offset = null) { return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams); } /** * Obțineți criterii de căutare. * * @return \Magento\Framework\Api\SearchCriteriaInterface|null */ funcția publică getSearchCriteria() { returnează nul; } /** * Setați criteriile de căutare. * * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria * @return $this * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ set de funcții publiceSearchCriteria(SearchCriteriaInterface $searchCriteria = null) { returnează $this; } /** * Obțineți numărul total. * * @return int */ funcția publică getTotalCount() { returnează $this->getSize(); } /** * Setați numărul total. * * @param int $totalCount * @return $this * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ funcția publică setTotalCount($totalCount) { returnează $this; } /** * Setați lista de articole. * * @param \Magento\Framework\Api\ExtensibleDataInterface[] $items * @return $this * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ funcția publică setItems(array $items = null) { returnează $this; } } ?>
3) Modificați colecția principală în modul descris mai jos (este important, deoarece colecția noastră personalizată este moștenită de la ea). Ar trebui să faceți următoarele modificări:
> app/code/Vendor/Rules/Model/ResourceModel/Rule/Collection.php
<?php namespace Vendor\Rules\Model\ResourceModel\Rule; Class Collection extinde \Magento\Rule\Model\ResourceModel\Rule\Collection\AbstractCollection { /** * Setați modelul de resurse și determinați maparea câmpului * * @return nul */ functie protejata _construct() { $this->_init('Vânzător\Reguli\Model\Regulă', 'Vânzător\Reguli\Model\ResourceModel\Regulă'); } /** * Filtrați colectarea după data specificată. * Filtrați colecția numai la regulile active. * * @param string|null $acum * @use $this->addStoreGroupDateFilter() * @return $this */ funcția publică setValidationFilter($acum = null) { dacă (!$this->getFlag('validation_filter')) { $this->addDateFilter($acum); $this->addIsActiveFilter(); $this->setOrder('sort_order', self::SORT_ORDER_DESC); $this->setFlag('validation_filter', true); } returnează $this; } /** * Filtru de la data sau pana la data * * @param $acum * @return $this */ funcția publică addDateFilter($acum) { $this->getSelect()->where( 'from_date este nulă sau from_date <= ?', $acum )->unde( „to_date este nul sau to_date >= ?”, $acum ); returnează $this; } } ?>
4) Apoi, eliminați vechiul marcaj din aspectul Grid și adăugați o listă de UI acolo:
> app/code/Vendor/Rules/view/adminhtml/layout/vendor_rules_example_rule_index.xml
<?xml version="1.0"?> <pagina xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <corp> <referenceBlock name="meniu"> <action method="setActive"> <argument name="itemId" xsi:type="string">Vendor_Rules::vendor_rules</argument> </acțiune> </referenceBlock> <referenceBlock name="page.title"> <action method="setTitleClass"> <argument name="class" xsi:type="string">complex</argument> </acțiune> </referenceBlock> <referenceContainer name="conținut"> <uiComponent name="vendor_rules_rule_listing"/> </referenceContainer> </corp> </pagina>
Practic, adăugăm doar ` vendor_rules_rule_listing ` menționat în conținutul paginii (acțiunea principală), schimbăm starea meniului nostru de produse la 'Activ' și setăm clasa de titlu.
5) La pasul următor, creăm lista UI, care va fi plasată aici:
> app/code/Vendor/Rules/view/adminhtml/ui_component/vendor_rules_rule_listing.xml
<?xml version="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> <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">adăugați</item> <item name="label" xsi:type="string" translate="true">Adăugați o regulă nouă</item> <item name="class" xsi:type="string">principal</item> <item name="url" xsi:type="string">*/*/newaction</item> </item> </item> </argument> <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"/> </item> </argument> </argument> <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> </item> </argument> </dataSource> <container name="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> </item> </argument> <bookmark name="marcaje"> <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> </item> </item> </argument> </bookmark> <component name="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> <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item> <item name="displayArea" xsi:type="string">dataGridActions</item> </item> </argument> </component> <filters name="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> <item name="templates" 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> </item> </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> </item> </item> <item name="observatori" xsi:type="array"> <item name="column" xsi:type="string">coloană</item> </item> </argument> </filtre> <paging name="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> <item name="selectProvider" xsi:type="string">vendor_rules_rule_listing.vendor_rules_rule_listing.vendor_rules_rule_columns.ids</item> </item> </argument> </paging> </container> <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">current</item> </item> </item> </argument> <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> </item> </argument> </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> <item name="config" xsi:type="array"> <item name="filter" xsi:type="string">textRange</item> <item name="dataType" xsi:type="string">text</item> <item name="sorting" xsi:type="string">asc</item> <item name="align" xsi:type="string">stânga</item> <item name="label" xsi:type="string" translate="true">ID</item> <item name="sortOrder" xsi:type="number">1</item> </item> </argument> </coloană> <column name="name"> <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> <item name="config" xsi:type="array"> <item name="filter" xsi:type="string">text</item> <item name="dataType" xsi:type="string">text</item> <item name="align" xsi:type="string">stânga</item> <item name="label" xsi:type="string" translate="true">Nume</item> </item> </argument> </coloană> <column name="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">Activ</item> </item> <item name="inactive" xsi:type="array"> <item name="value" xsi:type="string">0</item> <item name="label" xsi:type="string" translate="true">Inactiv</item> </item> </item> <item name="config" xsi:type="array"> <item name="filter" xsi:type="string">selectați</item> <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item> <item name="editor" xsi:type="string">selectați</item> <item name="dataType" xsi:type="string">selectați</item> <item name="label" xsi:type="string" translate="true">Este activ</item> <item name="sortOrder" xsi:type="number">65</item> </item> </argument> </coloană> <column name="sort_order"> <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> <item name="config" xsi:type="array"> <item name="filter" xsi:type="string">text</item> <item name="dataType" xsi:type="string">număr</item> <item name="align" xsi:type="string">stânga</item> <item name="label" xsi:type="string" translate="true">Prioritate</item> </item> </argument> </coloană> <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">data</item> <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item> <item name="label" xsi:type="string" translate="true">Începe</item> </item> </argument> </coloană> <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">data</item> <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item> <item name="label" xsi:type="string" translate="true">Sfârșit</item> </item> </argument> </coloană> <actionsColumn name="actions" class="Vendor\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> </item> </argument> </actionsColumn> </columns> <container name="sticky"> <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> </item> </argument> </container> </listing>
Lista ` dataSource ` conține o legătură către ` dataProvider ` – tipul pe care l-am creat în ` di.xml `. Conține datele de intrare necesare pentru Grid.
De aici, trebuie să definim cheia depusă - în cazul nostru este ` rule_id `.
În plus, puteți adăuga și butoanele personalizate, descrieți-le în secțiunea „butoane”. În exemplul nostru, am adăugat butonul standard „Adăugați” cu o adresă ` */*/newaction ` ( * în cale corespunde sensului curent).
` container name=”listing_top” ` conține câteva componente suplimentare de listă: filtre, paginare etc. Le poți schimba în funcție de cerințele tale personale.
` columns name=“vendor_rules_rule_columns” ` conține coloana care este aproape aceeași, ca în Grid implicită. Singura diferență semnificativă este o nouă coloană ` actionsColumn ` care introduce un set de acțiuni: editați și ștergeți. Aceste acțiuni pot fi, de asemenea, extinse, dacă este necesar.
După cum probabil ați observat, această coloană are o clasă nouă. Să învățăm cum îl putem crea:
> app/code/Vendor/Rules/Ui/Component/Listing/Column/RuleActions.php
<?php spațiu de nume Vendor\Rules\Ui\Component\Listing\Column; clasa RuleActions extinde \Magento\Ui\Component\Listing\Columns\Column { /** * Calea URL de editat * * @var șir */ const URL_PATH_EDIT = 'reguli_furnizor/regulă_exemplu/editare'; /** * Calea URL de șters * * @var șir */ const URL_PATH_DELETE = 'reguli_furnizor/regulă_exemplu/ștergere'; /** * Generator de adrese URL * * @var \Magento\Framework\UrlInterface */ protejat $urlBuilder; /** * Constructor * * @param \Magento\Framework\UrlInterface $urlBuilder * @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context * @param \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory * @param array $componente * @param array $date */ funcția publică __construct( \Magento\Framework\UrlInterface $urlBuilder, \Magento\Framework\View\Element\UiComponent\ContextInterface $context, \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory, matrice $componente = [], matrice $date = [] ) { $this->urlBuilder = $urlBuilder; parent::__construct($context, $uiComponentFactory, $componente, $date); } /** * Pregătiți sursa de date * * @param array $dataSource * @return matrice */ funcția publică prepareDataSource(array $dataSource) { dacă (!isset($dataSource['date']['items'])) { returnează $dataSource; } foreach ($dataSource['date']['items'] ca &$item) { dacă (!isset($item['rule_id'])) { continua; } $item[$this->getData('nume')] = [ 'editare' => [ 'href' => $this->urlBuilder->getUrl( static::URL_PATH_EDIT, [ 'id' => $item['rule_id'], ] ), 'label' => __('Editează'), ], 'șterge' => [ 'href' => $this->urlBuilder->getUrl( static::URL_PATH_DELETE, [ 'id' => $item['rule_id'], ] ), 'label' => __('Șterge'), 'confirma' => [ 'title' => __('Șterge "${ $.$data.name }"'), 'message' => __('Sunteți sigur că doriți să nu ștergeți regula "${ $.$data.name }"?'), ], ], ]; } returnează $dataSource; } } ?>
Această clasă este responsabilă de procesarea acțiunilor din Grid. De aici, este posibil să schimbați adresele URL sau numele parametrului transmis. În cazul nostru, cheia este rule_id (este transmisă sub numele „id”, pentru a ușura înțelegerea valorii sale).
Arata cam asa:
Dacă ați făcut totul corect, grila ar trebui să arate astfel:
După cum putem vedea din exemplu, este destul de ușor să transformați grila standard existentă în UI. Pe lângă extinderea funcționalității standard Grid, vă permite, de asemenea, să simplificați lucrul cu această parte a funcționalității Magento 2.
PS În următorul articol al seriei, vom descrie posibilitatea de a adăuga acțiuni în masă și coloane suplimentare.
Rămâneţi aproape!