[EDITAR em 3 de outubro de 2018]
Atualização para links para o devdocs: 2.0 - https://devdocs.magento.com/guides/v2.0/ui-components/ui-listing-grid.html e https://devdocs.magento.com/guides/v2. 0 / ui-components / ui-second.html
2.1 - https://devdocs.magento.com/guides/v2.1/ui_comp_guide/components/ui-listing-grid.html
2.2 - https://devdocs.magento.com/guides/v2.2/ui_comp_guide/components/ui-listing-grid.html
[EDIT 21 de janeiro de 2016]
A partir de 20/01/2016, o magento2 devdocs foi atualizado com a documentação estendida dos componentes da interface do usuário. Eu não o verifiquei extensivamente, mas elas podem conter mais informações do que a resposta que eu dei há alguns dias. Portanto, no interesse do seu tempo, você pode querer ver http://devdocs.magento.com/guides/v2.0/ui -library / ui-library-second.html
[/EDITAR]
Estou trabalhando com o Magento2 há mais de um mês e foi isso que notei sobre a nova maneira de criar grades.
Componente de grade da interface do Magento 2
1) arquivo de layout dentro de Company/Module/view/adminhtml/layout/module_controller_action.xml
definir grade como uiComponent com:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="styles"/>
<body>
<referenceContainer name="content">
<uiComponent name="listing_name"/>
</referenceContainer>
</body>
</page>
2) uiComponent é definido no Company/Module/view/adminhtml/ui_component/listing_name.xml
arquivo. O nome do arquivo deve ser igual ao nome do uiComponent usado no arquivo de layout. A estrutura do arquivo pode parecer bastante complexa à primeira vista, mas como sempre, esses são alguns nós repetidos. Para simplificar, vamos cortá-lo. O nó principal do arquivo de componente é <listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
. É fixo e acredito que requer o atributo de localização do espaço para nome. A seguir são tipicamente 4 nós dentro <listing />
nó: <argument />
, <dataSource />
, <container />
e <columns />
. Entretanto, essa não é uma configuração rigorosa, pois o <argument />
nó pode ser duplicado para fornecer mais configuração ou <container />
na listagem de páginas do cms que adiciona contêiner "pegajoso" por algum motivo.
O primeiro nó é <argument />
. Este nó define os dados para o componente. Geralmente você precisa fornecer algo como isto:
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">listing_name.listing_name_data_source</item>
<item name="deps" xsi:type="string">listing_name.listing_name_data_source</item>
</item>
<item name="spinner" xsi:type="string">listing_columns</item>
<item name="buttons" xsi:type="array">
<item name="add" xsi:type="array">
<item name="name" xsi:type="string">add</item>
<item name="label" xsi:type="string" translate="true">Add New Item</item>
<item name="class" xsi:type="string">primary</item>
<item name="url" xsi:type="string">*/*/new</item>
</item>
</item>
</argument>
<argument />
nó requer atributo name
. Nesse caso, data
define informações básicas sobre o componente. Ele contém vários <item />
nós para cada parte específica da configuração. js_config
informa ao componente onde é o provedor dos dados e dependências na configuração xml da listagem (que eu acho que é convertida em hash javascript). provider
O valor consiste no nome da listagem usado no arquivo de layout e no nome exclusivo da fonte de dados que será usado posteriormente. Nessas listagens, verifiquei o magento provider
e deps
são as mesmas. Não tenho certeza do que adianta ter isso diferente. spinner
leva o nome do nó em que as colunas da grade são definidas. buttons
permite adicionar botões ao topo da grade. Na maioria dos casos, seria apenas o Add new
botão. Os botões possuem alguns elementos:name
usado como identificação do elemento, label
é o que diz o botão, class
é a classe de botão e url
é o link para o qual aponta. Asteriks é substituído pela parte do URL atual. Outros possíveis <item />
nós de botão são: id
, title
, type
(reiniciar, enviar ou botão), onclick
(em vez de url
, ele tem precedência), style
, value
, disabled
. O elemento Button é renderizado por Magento\Ui\Component\Control\Button
classe.
Em seguida, temos o <dataSource />
nó:
<dataSource name="listing_name_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">UniqueNameGridDataProvider</argument>
<argument name="name" xsi:type="string">listing_name_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">database_id</argument>
<argument name="requestFieldName" xsi:type="string">request_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>
name
usado no <dataSource />
nó deve corresponder ao usado em argument/js_config/provider
e argument/js_config/deps
. O próximo nó define qual classe é responsável pela preparação dos dados para a grade. class
O argumento requer um nome exclusivo que corresponderá di.xml
. primaryFieldName
refere-se à coluna principal do banco de dados e requestFieldName
à variável nas solicitações http. Eles podem ser iguais, mas não precisam, a listagem de páginas do CMS usa page_id
como primaryFieldName
e id
como requestFieldName
. update_url
refere-se ao ponto de entrada para o qual as chamadas do ajax para filtragem e classificação são enviadas. O segundo argumento em <dataSource />
refere-se ao arquivo javascript que lida com js parte do envio e processamento de chamadas ajax para a grade. O arquivo padrão é Magento/Ui/view/base/web/js/grid/provider.js
.
Outro nó é <container />
.
<container name="listing_top"> ... </container>
Como ele contém muitos dados, deixe-os dividir também. Seus filhos são as partes da página inteira. Primeiro filho <argument />
:
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">ui/grid/toolbar</item>
</item>
</argument>
Ele define o modelo de knockout responsável por manipular o layout e todas as ações e, por padrão, aponta para Magento/Ui/view/base/web/templates/grid/toolbar.html
O próximo nó é (ou pode ser) <bookmark />
<bookmark name="bookmarks">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="namespace" xsi:type="string">listing_name</item>
</item>
</item>
</argument>
</bookmark>
Este nó adiciona recurso de marcador à grade. Ele permite ao administrador configurar diferentes "perfis" da grade que exibe colunas diferentes. Graças a isso, você pode adicionar todas as colunas da tabela à grade e deixar que o usuário decida quais informações são relevantes para ele. namespace
deve corresponder ao nome usado no arquivo de layout.
Outro nó é <component />
<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">listing_name.listing_name.listing_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>
Temos 3 valores para configurar aqui. Primeiro é o provider
que segue o padrão [nome_da_listagem_do_layout]. [Nome_da_listagem_do_layout]. [Nome_da_coluna_nome_da_coluna] (como na listagem / argumento / spinner do nó). component
refere-se ao arquivo js que exibe grade e, por padrão, pontos para os Magento/Ui/view/base/web/js/grid/controls/columns.js
quais usa modelo Magento/Ui/view/base/web/templates/grid/controls/columns.html
. O último item é o displayArea
que define onde os controles da coluna precisam ser exibidos. Refere-se ao getRegion('dataGridActions')
arquivo definido em container/argument/config/template
(padrão Magento/Ui/view/base/web/templates/grid/toolbar.html
:).
O próximo nó é <filterSearch />
<filterSearch name="fulltext">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="provider" xsi:type="string">listing_name.listing_name_data_source</item>
<item name="chipsProvider" xsi:type="string">listing_name.listing_name.listing_top.listing_filters_chips</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">listing_name.listing_name.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.search</item>
</item>
</item>
</argument>
</filterSearch>
Este nó adiciona uma pesquisa de texto completo à página. Ele está localizado acima da grade como um campo de entrada de texto único, com "Pesquisar por palavra-chave" como espaço reservado. Não tenho certeza de quais opções são possíveis aqui, pois não brinquei muito com isso, mas o list_filters_chips se refere ao Magento/Ui/view/base/web/js/grid/filters/chips.js
arquivo.
O próximo nó é <filters />
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsProvider" xsi:type="string">listing_name.listing_name.listing_columns</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">listing_name.listing_name.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">listing_name.listing_name.listing_top.listing_filters</item>
<item name="imports" xsi:type="array">
<item name="visible" xsi:type="string">listing_name.listing_name.listing_columns.${ $.index }:visible</item>
</item>
</item>
</item>
<item name="observers" xsi:type="array">
<item name="column" xsi:type="string">column</item>
</item>
</argument>
</filters>
Este nó define a configuração da filtragem de colunas que é visível após clicar no botão "Filtros" na parte superior direita acima da grade. columnsProvider
segue uma estrutura semelhante aos nós anteriores, portanto, [nome_da_listagem_do_layout]. [nome_da_listagem_do_layout]. [nome_da_coluna_nome_da_coluna]. storegeConfig
vai como [nome_da_listagem_do_layout]. [nome_da_listagem_do_layout]. [nome_do_nó_pacote] [nome_do_do_marcador_do_marcador]. No templates
nó do item, você pode definir quais arquivos são usados para renderizar opções de filtro específicas. Nesse caso, apenas selecionar é definido e usa Magento/Ui/view/base/web/js/form/element/ui-select.js
como component
e Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html
como modelo de nocaute. Olhe Magento/Ui/view/base/web/js/form/element
para ver outras possibilidades. Somente select é definido aqui para substituir os valores padrão: Magento/Ui/view/base/web/js/form/element/select.js
e Magento/Ui/view/base/web/templates/grid/filters/elements/select.html
. Os valores padrão para filtros e outros nós são definidos em Magento/Ui/view/base/ui_component/etc/definition.xml
.
O próximo nó é <massAction />
e permite adicionar ação em massa, selecionar à grade
<massaction name="listing_massaction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="selectProvider" xsi:type="string">listing_name.listing_name.listing_columns.ids</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
<item name="indexField" xsi:type="string">database_id</item>
</item>
</argument>
<action name="delete">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="type" xsi:type="string">delete</item>
<item name="label" xsi:type="string" translate="true">Delete</item>
<item name="url" xsi:type="url" path="*/*/massDelete"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Delete items</item>
<item name="message" xsi:type="string" translate="true">Are you sure you wan't to delete selected items?</item>
</item>
</item>
</argument>
</action>
<action name="change_status">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="type" xsi:type="string">change_status</item>
<item name="label" xsi:type="string" translate="true">Change Status</item>
</item>
</argument>
<argument name="actions" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Company\Module\Ui\Component\MassAction\Status\Options</argument>
<argument name="data" xsi:type="array">
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Change Status</item>
<item name="message" xsi:type="string" translate="true">Are you sure to change status for selected feed(s)?</item>
</item>
</argument>
</argument>
</action>
</massaction>
name
argumento deve ser único. O primeiro nó filho <argument />
define dados básicos. provider
segue a mesma estrutura que outros nós e refere-se às colunas nome do nó e sua coluna de IDs. Esta coluna conterá caixas de seleção com itens selecionados para a ação em massa a ser processada. component
define qual arquivo é usado para renderizar e manipular a ação em massa. O valor padrão é Magento_Ui/js/grid/massactions
(aponta para Magento/Ui/view/base/web/js/grid/massactions.js
). Você pode usar Magento_Ui/js/grid/tree-massactions
para adicionar estrutura em árvore. No caso acima, eu o uso para adicionar a ação "Alterar status", que mostra as opções "ativar" e "desativar". Após o <argument />
nó, você pode adicionar quantos <action />
nós quantas ações desejar. Cada <action />
nó segue um esquema semelhante. No primeiro caso (ação de exclusão), o nó requer um nome exclusivo. Em seguida, argument
contém a configuração em quelabel
é o que é visível na opção de seleção, url
ponto final para enviar dados e confirm
adiciona o modal de confirmação antes do envio. No caso de "Alterar status", a ação url
no primeiro argument
nó é omitida, pois os URLs são fornecidos por status, por classe definida no segundo argument
nó. A classe deve implementar a interface Zend \ Stdlib \ JsonSerializable. Verifique Magento\Customer\Ui\Component\MassAction\Group\Options
como referência.
Finalmente, no <container />
nó, temos o <paging />
nó que define a paginação.
<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">listing_name.listing_name.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.paging</item>
</item>
<item name="selectProvider" xsi:type="string">listing_name.listing_name.listing_columns.ids</item>
</item>
</argument>
</paging>
Estrutura para provider
e selectProvider
deve ficar clara agora.
E o último nó da grade básica é <columns />
. Ele contém todas as definições de colunas disponíveis para uso pelo administrador. O nó é definido como
<columns name="listing_columns"> ... </columns>
e o atributo name é usado em outros nós quando se refere a ele. O primeiro filho é
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">listing_name.listing_name.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current</item>
</item>
<item name="childDefaults" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">listing_name.listing_name.listing_top.bookmarks</item>
<item name="root" xsi:type="string">columns.${ $.index }</item>
<item name="namespace" xsi:type="string">current.${ $.storageConfig.root}</item>
</item>
<item name="fieldAction" xsi:type="array">
<item name="provider" xsi:type="string">name_listing.name_listing.listing_columns.actions</item>
<item name="target" xsi:type="string">applyAction</item>
<item name="params" xsi:type="array">
<item name="0" xsi:type="string">edit</item>
<item name="1" xsi:type="string">${ $.$data.rowIndex }</item>
</item>
</item>
</item>
</item>
</argument>
O que fiz aqui foi fornecer apenas os provider
valores corretos seguindo o esquema usado na listagem. fieldAction
O nó permite definir a ação que é acionada quando clicada na célula. As configurações padrão chamam a ação de edição
Proximo é <selectionColumns />
<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">id</item>
</item>
</argument>
</selectionsColumn>
Este nó define a coluna com caixas de seleção para ação em massa a ser usada. Seus nomes são referidos após o ponto em vários nós descritos acima.
Depois disso, você pode adicionar qualquer número de colunas no mesmo formato:
<column name="name" class="Company\Module\Ui\Component\Listing\Column\Name">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">Company\Module\Model\Source\Type</item>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">select</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
<item name="dataType" xsi:type="string">select</item>
<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
<item name="label" xsi:type="string" translate="true">Name</item>
<item name="sortOrder" xsi:type="number">80</item>
<item name="visible" xsi:type="boolean">false</item>
</item>
</argument>
</column>
Nem todos os nós dos itens internos são necessários. Eles estão definindo:
filter
- tipo de filtro da coluna. Isso é usado no bloco de filtros. Os valores disponíveis são: texto, seleção, dateRange. Se a seleção for usada <item name="options">...</item>
, será usada como uma classe que fornece opções para a seleção de filtro.
component
- define os arquivos js que são usados para renderizar a coluna. As opções disponíveis são em Magento/Ui/view/base/web/js/grid/columns/*
. selecionar é fornecido, o filtro está definido para selecionar. Para filtro de texto, esse valor não é necessário.
dataType
- fornece informações do tipo de dados usado para o valor da coluna. Para select use select também, for dateRange use date
bodyTmpl
- define o arquivo html usado pelo knockout para renderizar a célula. Por padrão, interface do usuário / grade / células / texto é usado ( Magento/Ui/view/base/web/templates/grid/cells/text.html
). Outras opções estão localizadas no Magento/Ui/view/base/web/templates/grid/cells/*
diretório ui/grid/cells/html
permite usar o conteúdo html na célula.
label
- isso será exibido no cabeçalho da coluna e no bloco de filtro
sortOrder
- encomenda
visible
- exibir ou não a coluna. Isso pode ser usado para definir colunas para marcadores, mas não as mostra por padrão.
No final, você pode adicionar uma coluna de ações, que pode ser usada para o item único
<actionsColumn name="actions" class="Company\Module\Ui\Component\Listing\Column\Actions">
<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">107</item>
<item name="indexField" xsi:type="string">database_id</item>
</item>
</argument>
</actionsColumn>
indexField
refere-se ao nome da coluna no banco de dados. A classe Actions deve estender Magento\Ui\Component\Listing\Columns\Column
e definir o prepareDataSource
método. Veja Magento/Cms/Ui/Component/Listing/Column/PageActions.php
como referência
3) para finalizar a grade, precisamos definir alguns elementos em Company / Module / etc / di.xml
Primeiro, definimos a classe do provedor que foi usada no nó dataSource/class
<virtualType name="UniqueNameGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
<arguments>
<argument name="collection" xsi:type="object" shared="false">Company\Module\Model\Resource\Item\Collection</argument>
<argument name="filterPool" xsi:type="object" shared="false">UniqueNameItemIdFilterPool</argument>
</arguments>
</virtualType>
collection
resolve para a classe de coleção padrão e filerPool
define novo elemento:
<virtualType name="UniqueNameItemIdFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
<arguments>
<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>
</arguments>
</virtualType>
Evidentemente, isso tem a ver com filtragem e pesquisa. Por enquanto, eu sempre usei os valores padrão.
Agora registramos nossa fonte de dados:
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="listing_name_data_source" xsi:type="string">Company\Module\Model\Resource\Item\Grid\Collection</item>
</argument>
</arguments>
</type>
Nesse caso, o nome do nó deve corresponder ao usado no <dataSource />
nó na listagem de xml e resolve não a coleção, mas a classe GridCollection. Ele deve estender a classe de coleção regular e implementar adicionalmente Magento\Framework\Api\Search\SearchResultInterface
.
No final, configuramos nossa coleção de grades (os nomes dos argumentos são bastante óbvios)
<type name="Company\Module\Model\Resource\Item\Grid\Collection">
<arguments>
<argument name="mainTable" xsi:type="string">database_table_name</argument>
<argument name="eventPrefix" xsi:type="string">name_for_events</argument>
<argument name="eventObject" xsi:type="string">event_object_name</argument>
<argument name="resourceModel" xsi:type="string">Company\Module\Model\Resource\Item</argument>
</arguments>
</type>