Magento2实现CRUD操作功能

        之前学习了如果创建一个简单的模块,包括创建目录结构,定义模块,创建registration.php 文件和 module.xml 文件,接下来要学习一下如何去实现在模块中去实现CRUD功能。

1.创建模块的基本结构

在之前Vendor_HelloWorld模块目录中添加新文件实现CRUD功能

app/
└── code/
    └── Vendor/
        └── HelloWorld/
            ├── Block/
            │   └── Adminhtml/
            │       └── Item/
            │           ├── Edit/
            │           │   └── Form.php
            │           └── Edit.php 
            ├── Controller/
            │   ├── Adminhtml/
            │   │   └── Item/
            │   │       ├── Index.php
            │   │       ├── Edit.php
            │   │       ├── Save.php
            │   │       ├── NewAction.php
            │   │       ├── MassDelete.php
            │   │       └── Delete.php
            │   └── Index/
            │       └── Index.php
            │
            ├── etc/
            │   ├── adminhtml/
            │   │   ├── menu.xml
            │   │   └── routes.xml
            │   ├── frontend/
            │   │   └── routes.xml
            │   ├── module.xml
            │   ├── acl.xml
            │   └── di.xml
            │
            ├── Model/
            │   ├── ResourceModel/
            │   │   ├── Item/
            │   │   │   └── Collection.php
            │   │   └── Item.php
            │   └── Item.php
            │
            ├── Setup/
            │   └── InstallSchema.php
            │ 
            ├── Ui/
            │   └── Component/
            │       └── Listing/
            │           └── Column/
            │               └── Actions.php
            │
            └── view/
                ├── adminhtml/
                │   ├── layout/
                │   │   ├── helloworld_item_index.xml
                │   │   └── helloworld_item_edit.xml
                │   └── ui_component/
                │       └── helloworld_item_listing.xml
                └── frontend/
                    ├── layout/
                    │   └── helloworld_index_index.xml
                    └── templates/
                        └── hello.phtml   

这个目录结构是在之前Vendor_HelloWorld模块中新增了一些文件以及目录,包括,CRUD操作的控制器、Model类、安装数据库的类方法,以及UI组件的目录,接下来安装这个目录来一步一步创建该模块来实现CRUD操作

2.创建InstallSchema文件

在实现CRUD操作之前,需要先通过InstallSchema文件来创建数据表,Magento的创建数据表的操作是通过创建InstallSchema文件来实现的,在该方法中去添加表的名称以及表中的字段名称、字段类型.

app/code/Vendor/HelloWorld/Setup/InstallSchema.php

<?php

namespace Vendor\HelloWorld\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class InstallSchema implements InstallSchemaInterface
{
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        if (!$setup->tableExists('helloworld_items')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('helloworld_items')
            )
                ->addColumn(
                    'item_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'nullable' => false, 'primary' => true, 'unsigned' => true],
                    'Item ID'
                )
                ->addColumn(
                    'name',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => false],
                    'Item Name'
                )
                ->addColumn(
                    'description',
                    Table::TYPE_TEXT,
                    '64k',
                    [],
                    'Item Description'
                )
                ->addColumn(
                    'is_active',
                    Table::TYPE_SMALLINT,
                    null,
                    ['nullable' => false, 'default' => '1'],
                    'Is Active'
                )
                ->addColumn(
                    'created_at',
                    Table::TYPE_TIMESTAMP,
                    null,
                    ['nullable' => false, 'default' => Table::TIMESTAMP_INIT],
                    'Created At'
                )
                ->addColumn(
                    'updated_at',
                    Table::TYPE_TIMESTAMP,
                    null,
                    ['nullable' => false, 'default' => Table::TIMESTAMP_INIT_UPDATE],
                    'Updated At'
                )
                ->setComment('Helloworld Items Table');

            $setup->getConnection()->createTable($table);
        }

        $setup->endSetup();
    }
}

3.创建Model类方法

        在创建完Model目录之后,首先需要创建三个类:模型类Item.php、资源模型类ResourceModel/Item.php、集合类ResourceModel/Item/Collection.php,这三个类方法是用于数据库之间进行交互。

首先创建模型类Item.php:

app/code/Vendor/HelloWorld/Model/Item.php

<?php

namespace Vendor\HelloWorld\Model;

use Magento\Framework\Model\AbstractModel;
use Vendor\HelloWorld\Api\Data\ItemInterface;

class Item extends AbstractModel implements ItemInterface
{
    protected function _construct()
    {
        $this->_init('Vendor\HelloWorld\Model\ResourceModel\Item');
    }
}

在上面的代码中,Item模型类继承自AbstractModel类,并通过_init()方法将其与对应的资源模型类关联起来。

创建资源模型类ResourceModel/Item.php:

app/code/Vendor/HelloWorld/Model/ResourceModel/Item.php

<?php

namespace Vendor\HelloWorld\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class Item extends AbstractDb
{
    protected function _construct()
    {
        $this->_init('helloworld_items', 'item_id');
    }
}

在这里,Item资源模型类继承自AbstractDb,并使用_init()方法指定数据库表helloworld_items及其主键item_id。

创建集合类ResourceModel/Item/Collection.php:

app/code/Vendor/HelloWorld/Model/ResourceModel/Item/Collection.php

<?php

namespace Vendor\HelloWorld\Model\ResourceModel\Item;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
{
    protected $_idFieldName = 'item_id';
    protected function _construct()
    {
        $this->_init('Vendor\HelloWorld\Model\Item', 'Vendor\HelloWorld\Model\ResourceModel\Item');
    }
}

总结

  • 模型类 (Model):用于表示数据库表中的一条记录,封装数据操作的逻辑,负责对单行数据进行增删改查。

  • 资源模型类 (ResourceModel):负责与数据库交互,定义数据库的具体操作。它直接与数据库表关联,实现CRUD操作。

  • 集合类 (Collection):用于加载多条数据记录,通常用于展示列表。它可以实现分页、过滤和排序功能,方便在管理后台中展示数据。

通过将这三类类文件分离,Magento 2实现了数据访问逻辑和业务逻辑的解耦

4.创建控制器

创建完类方法之后,接下来需要创建用于处理CRUD操作的控制器,如Index.php、NewAction.php、Edit.php、Save.php、Delete.php

创建Index.php

创建Index作为首页的控制器

app/code/Vendor/HelloWorld/Controller/Adminhtml/Item/Index.php

<?php

namespace Vendor\HelloWorld\Controller\Adminhtml\Item;

use Magento\Backend\App\Action;
use Magento\Framework\View\Result\PageFactory;

class Index extends Action
{
    protected $resultPageFactory;

    public function __construct(
        Action\Context $context,
        PageFactory $resultPageFactory
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
    }

    public function execute()
    {
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu('Vendor_HelloWorld::item');
        $resultPage->getConfig()->getTitle()->prepend(__('Items'));

        return $resultPage;
    }
}

创建NewAction.php

创建NewAction.php作为Edit控制器的转发

app/code/Vendor/HelloWorld/Controller/Adminhtml/Item/NewAction.php

<?php

namespace Vendor\HelloWorld\Controller\Adminhtml\Item;

use Magento\Backend\App\Action;
use Magento\Framework\View\Result\PageFactory;

class NewAction extends Action
{
    /**
     * @var PageFactory
     */
    protected $resultPageFactory;

    /**
     * @var ForwardFactory
     */
    protected $resultForwardFactory;

    /**
     * 构造函数
     *
     * @param Action\Context $context
     * @param PageFactory $resultPageFactory
     * @param ForwardFactory $resultForwardFactory
     */
    public function __construct(
        Action\Context $context,
        PageFactory $resultPageFactory,
        \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
        $this->resultForwardFactory = $resultForwardFactory;
    }

    /**
     * 执行方法
     *
     * @return \Magento\Framework\Controller\Result\Redirect
     */
    public function execute()
    {
        // 转发到 edit 动作
        $resultForward = $this->resultForwardFactory->create();
        return $resultForward->forward('edit');
    }
}

NewAction.php通常用于处理创建新记录的页面请求,例如点击“新增”按钮后进入的页面

创建Edit.php

Edit.php作为表单提交页面的控制器,主要用于表单提交

app/code/Vendor/HelloWorld/Controller/Adminhtml/Item/Edit.php

<?php

namespace Vendor\HelloWorld\Controller\Adminhtml\Item;

use Magento\Backend\App\Action;
use Magento\Framework\View\Result\PageFactory;
use Vendor\HelloWorld\Model\ItemFactory;
use Magento\Framework\Registry;

class Edit extends Action
{
    protected $resultPageFactory;
    protected $itemFactory;
    protected $_coreRegistry;

    public function __construct(
        Action\Context $context,
        PageFactory $resultPageFactory,
        ItemFactory $itemFactory,
        Registry $registry
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
        $this->itemFactory = $itemFactory;
        $this->_coreRegistry = $registry;
    }

    public function execute()
    {
        $id = $this->getRequest()->getParam('item_id');
        $model = $this->itemFactory->create();

        if ($id) {
            $model->load($id);
            if (!$model->getId()) {
                $this->messageManager->addErrorMessage(__('This item no longer exists.'));
                $this->_redirect('*/*/');
                return;
            }
        }

        $data = $this->_session->getFormData(true);
        if (!empty($data)) {
            $model->setData($data);
        }

        $this->_coreRegistry->register('helloworld_item', $model);
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu('Vendor_HelloWorld::item');
        $resultPage->getConfig()->getTitle()->prepend($model->getId() ? __('Edit Item') : __('New Item'));
        return $resultPage;
    }
}

创建Save.php

创建Save控制器来执行对于表单提交数据的保存

app/code/Vendor/HelloWorld/Controller/Adminhtml/Item/Save.php

<?php

namespace Vendor\HelloWorld\Controller\Adminhtml\Item;

use Magento\Backend\App\Action;
use Vendor\HelloWorld\Model\ItemFactory;

class Save extends Action
{
    protected $itemFactory;

    public function __construct(
        Action\Context $context,
        ItemFactory $itemFactory
    ) {
        parent::__construct($context);
        $this->itemFactory = $itemFactory;
    }

    public function execute()
    {
        $data = $this->getRequest()->getPostValue();
        if (!$data) {
            $this->_redirect('*/*/');
            return;
        }

        try {
            $model = $this->itemFactory->create();
            $model->setData($data);
            if (isset($data['id'])) {
                $model->setId($data['id']);
            }
            $model->save();
            $this->messageManager->addSuccessMessage(__('Item saved successfully.'));
            $this->_redirect('*/*/');
        } catch (\Exception $e) {
            $this->messageManager->addErrorMessage($e->getMessage());
            $this->_redirect('*/*/edit', ['id' => $this->getRequest()->getParam('id')]);
        }
    }
}

创建Delete.php

创建Delete来实现对于指定id数据的删除

app/code/Vendor/HelloWorld/Controller/Adminhtml/Item/Delete.php

<?php

namespace Vendor\HelloWorld\Controller\Adminhtml\Item;

use Magento\Backend\App\Action;
use Vendor\HelloWorld\Model\ItemFactory;

class Delete extends Action
{
    protected $itemFactory;

    public function __construct(
        Action\Context $context,
        ItemFactory $itemFactory
    ) {
        parent::__construct($context);
        $this->itemFactory = $itemFactory;
    }

    public function execute()
    {
        $id = $this->getRequest()->getParam('item_id');
        if ($id) {
            try {
                $model = $this->itemFactory->create();
                $model->load($id);
                $model->delete();
                $this->messageManager->addSuccessMessage(__('Item deleted successfully.'));
                $this->_redirect('*/*/');
            } catch (\Exception $e) {
                $this->messageManager->addErrorMessage($e->getMessage());
                $this->_redirect('*/*/edit', ['id' => $id]);
            }
        } else {
            $this->messageManager->addErrorMessage(__('We can\'t find an item to delete.'));
            $this->_redirect('*/*/');
        }
    }
}

创建MassDelete.php

这个控制器主要是实现数据的批量删除

app/code/Vendor/HelloWorld/Controller/Adminhtml/Item/MassDelete.php

<?php
namespace Vendor\HelloWorld\Controller\Adminhtml\Item;

use Magento\Backend\App\Action;
use Magento\Framework\Controller\ResultFactory;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Vendor\HelloWorld\Model\ResourceModel\Item\CollectionFactory;

class MassDelete extends Action
{
    protected $filter;
    protected $collectionFactory;

    public function __construct(Context $context, Filter $filter, CollectionFactory $collectionFactory)
    {
        $this->filter = $filter;
        $this->collectionFactory = $collectionFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        $collection = $this->filter->getCollection($this->collectionFactory->create());
        $collectionSize = $collection->getSize();

        foreach ($collection as $page) {
            $page->delete();
        }

        $this->messageManager->addSuccessMessage(__('A total of %1 record(s) have been deleted.', $collectionSize));

        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);

        return $resultRedirect->setPath('*/*/');
    }
}

5.创建视图

在创建好控制器以及模型之后,对于页面的展示需要来创建对应的视图文件,该功能中主要涉及两个页面一个是首页的列表页面,这个通过Magento的Ui组件来进行实现,还有一个页面是表单提交页面,主要通过Block中创建表单类方法来实现。

同之前一样创建后端的adminhtml目录,并创建layout布局目录,因为涉及到Ui组件,因此要创建一个ui_component目录来存放ui文件。

在layout创建helloworld_item_index.xml、helloworld_item_edit.xml文件

app/code/Vendor/HelloWorld/view/adminhtml/layout/helloworld_item_index.xml

<?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">
    <body>
        <referenceContainer name="content">
            <uiComponent name="helloworld_item_listing"/>
        </referenceContainer>
    </body>
</page>

app/code/Vendor/HelloWorld/view/adminhtml/layout/helloworld_item_edit.xml

<?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">
    <body>
        <referenceContainer name="content">
            <block class="Vendor\HelloWorld\Block\Adminhtml\Item\Edit" name="helloworld_item_edit">
                <block class="Vendor\HelloWorld\Block\Adminhtml\Item\Edit\Form" name="helloworld_item_edit_form"/>
            </block>
        </referenceContainer>
    </body>
</page>

创建完成之后,对于helloworld_item_index.xml文件,采用Ui组件的形式创建的,因此要创建ui_component/helloworld_item_listing.xml 文件

app/code/Vendor/HelloWorld/view/adminhtml/ui_component/helloworld_item_listing.xml

<?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"> <!-- Define JavaScript Configuration -->
            <item name="provider" xsi:type="string">helloworld_item_listing.helloworld_item_listing_data_source</item> <!-- source provider -->
            <item name="deps" xsi:type="string">helloworld_item_listing.helloworld_item_listing_data_source</item> <!-- depend data source  -->
        </item>
        <item name="spinner" xsi:type="string">helloworld_item_columns</item> <!-- A loading indicator while data is loading-->
        <item name="buttons" xsi:type="array">
            <item name="add" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">Add New Item</item>
                <item name="class" xsi:type="string">primary</item> <!-- Main button-->
                <item name="url" xsi:type="string">*/*/new</item>
            </item>
        </item>
    </argument>
    <!-- DataProvider -->
    <dataSource name="helloworld_item_listing_data_source"> <!-- Define a data source component-->
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument> <!-- Data provider class-->
            <argument name="name" xsi:type="string">helloworld_item_listing_data_source</argument> <!-- DataProvider name -->
            <argument name="primaryFieldName" xsi:type="string">item_id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument> <!-- URL request id -->
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="update_url" xsi:type="url" path="mui/index/render"/> <!-- This is Magento\Ui\Controller\Index\Render -->
                    <item name="storageConfig" xsi:type="array">
                        <item name="indexField" xsi:type="string">id</item> <!-- listing index -->
                    </item>
                </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> <!-- JS component path-->
            </item>
        </argument>
    </dataSource>
    <!-- DataProvider -->
    <listingToolbar name="listing_top"> <!-- Top tools list -->
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="sticky" xsi:type="boolean">true</item> <!-- Sticky Toolbar will be fixed at the top of table -->
            </item>
        </argument>
        <bookmark name="bookmarks"/>
        <columnsControls name="columns_controls"/> <!-- Controller columns display or hide -->
        <filters name="listing_filters">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <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> <!-- Frontend components-->
                                <item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item> <!--Display path -->
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </filters>
        <massaction name="listing_massaction">
            <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="helloworld/item/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 to delete selected item(s)?</item>
                        </item>
                    </item>
                </argument>
            </action>
        </massaction>
        <paging name="listing_paging"/> <!-- Paging control-->
    </listingToolbar>
    <columns name="helloworld_item_columns">
        <selectionsColumn name="ids">
            <settings>
                <indexField>item_id</indexField>
                <resizeEnabled>false</resizeEnabled>
                <resizeDefaultWidth>55</resizeDefaultWidth>
            </settings>
        </selectionsColumn>
        <column name="item_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                </item>
            </argument>
        </column>
        <column name="name">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Name</item>
                    <item name="editor" xsi:type="string">text</item>
                </item>
            </argument>
        </column>
        <column name="description">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Description</item>
                    <item name="editor" xsi:type="string">text</item>
                </item>
            </argument>
        </column>
        <column name="is_active">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Is Active</item>
                    <item name="options" xsi:type="array">
                        <item name="1" xsi:type="array">
                            <item name="value" xsi:type="string">1</item>
                            <item name="label" xsi:type="string">Yes</item>
                        </item>
                        <item name="0" xsi:type="array">
                            <item name="value" xsi:type="string">0</item>
                            <item name="label" xsi:type="string">No</item>
                        </item>
                    </item>
                </item>
            </argument>
        </column>
        <actionsColumn name="actions" class="Vendor\HelloWorld\Ui\Component\Listing\Column\Actions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="sortable" xsi:type="boolean">false</item>
                    <item name="sortOrder" xsi:type="number">100</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>

6.创建etc下的配置文件

该模块为后端的菜单模块,因此需要创建acl.xml文件来为用户定义权限

app/code/Vendor/HelloWorld/etc/acl.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Vendor_HelloWorld::item" title="Item Page" sortOrder="10"/>
            </resource>
        </resources>
    </acl>
</config>

除了acl.xml文件还需要创建的是menu.xml以及routes.xml文件,其功能跟之前admin模块创建的功能相同。

app/code/Vendor/HelloWorld/etc/adminhtml/menu.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <menu>
        <add id="Vendor_HelloWorld::item"
             title="HelloWorld Items"
             module="Vendor_HelloWorld"
             sortOrder="10"
             parent="Magento_Backend::content"
             action="helloworld/item"
             resource="Vendor_HelloWorld::item"/>
    </menu>
</config>

app/code/Vendor/HelloWorld/etc/adminhtml/routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="helloworld" frontName="helloworld">
            <module name="Vendor_HelloWorld" />
        </route>
    </router>
</config>

在使用ui组件中有一段代码如下:

    <dataSource name="helloworld_item_listing_data_source"> <!-- Define a data source component-->
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument> <!-- Data provider class-->
            <argument name="name" xsi:type="string">helloworld_item_listing_data_source</argument> <!-- DataProvider name -->
            <argument name="primaryFieldName" xsi:type="string">item_id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument> <!-- URL request id -->
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="update_url" xsi:type="url" path="mui/index/render"/> <!-- This is Magento\Ui\Controller\Index\Render -->
                    <item name="storageConfig" xsi:type="array">
                        <item name="indexField" xsi:type="string">id</item> <!-- listing index -->
                    </item>
                </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> <!-- JS component path-->
            </item>
        </argument>
    </dataSource>

这部分代码是指定了ui组件对应的数据源,对于ui组件指定的数据源要通过一个di.xml文件来进行依赖注入

app/code/Vendor/HelloWorld/etc/adminhtml/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!--Grid collection-->
    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="helloworld_item_listing_data_source" xsi:type="string">Vendor\HelloWorld\Model\ResourceModel\Item\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
    <virtualType name="Vendor\HelloWorld\Model\ResourceModel\Item\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">helloworld_items</argument>
            <argument name="resourceModel" xsi:type="string">Vendor\HelloWorld\Model\ResourceModel\Item</argument>
        </arguments>
    </virtualType>
</config>

指定了ui组件对应的数据源来自Vendor\HelloWorld\Model\ResourceModel\Item 类

所有etc配置文件就到这创建完成了

7.创建UI操作列对应类

在创建ui组件中有一个组件是对于列表进行列操作的,其实现的类方法是app/code/Vendor/HelloWorld/ui/Component/Listing/Column/Actions.php

<?php


namespace Vendor\HelloWorld\Ui\Component\Listing\Column;

use Magento\Framework\UrlInterface;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;

/**
 * Class Actions
 * @package Vendor\HelloWorld\Ui\Component\Listing\Column
 */
class Actions extends Column
{
    /**
     * @var UrlInterface
     */
    private $urlBuilder;

    /**
     * Actions constructor.
     *
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param UrlInterface $urlBuilder
     * @param array $components
     * @param array $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        UrlInterface $urlBuilder,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);

        $this->urlBuilder = $urlBuilder;
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     *
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {

                $item[$this->getData('name')] = [
                    'delete' => [
                        'href'    => $this->urlBuilder->getUrl('helloworld/item/delete', ['item_id' => $item['item_id']]),
                        'label'   => __('Delete'),
                        'confirm' => [
                            'title'   => __('Delete'),
                            'message' => __('Are you sure you want to delete this item?')
                        ]
                    ],
                ];
            }
        }

        return $dataSource;
    }
}

该类主要是实现了列操作的类方法实现

8.创建Block目录

对于helloworld_item_edit.xml文件需要创建一个Block目录,为这个布局创建两个视图类,来作为表单页面的生成。

首先创建Edit.php实现父区块(block)的创建:

app/code/Vendor/HelloWorld/Block/Adminhtml/Item/Edit.php

<?php
namespace Vendor\HelloWorld\Block\Adminhtml\Item;

use Magento\Backend\Block\Widget\Form\Container;

class Edit extends Container
{
    protected function _construct()
    {
        $this->_objectId = 'item_id';
        $this->_blockGroup = 'Vendor_HelloWorld';
        $this->_controller = 'adminhtml_item';

        parent::_construct();

        $this->buttonList->update('save', 'label', __('Save Item'));
        $this->buttonList->update('back', 'label', __('GO Back'));
        $this->buttonList->remove('reset');
    }

}

其次创建Form.php实现子区块(block)的创建:
app/code/Vendor/HelloWorld/Block/Adminhtml/Item/Edit/Form.php

<?php

namespace Vendor\HelloWorld\Block\Adminhtml\Item\Edit;

use Magento\Backend\Block\Widget\Form\Generic;
use Magento\Framework\Data\FormFactory;
use Magento\Framework\Registry;

class Form extends Generic
{
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        Registry $registry,
        FormFactory $formFactory,
        array $data = []
    ) {
        parent::__construct($context, $registry, $formFactory, $data);
    }

    protected function _prepareForm()
    {
        // 从注册表中获取模型
        $model = $this->_coreRegistry->registry('helloworld_item');


        // 创建表单
        $form = $this->_formFactory->create(
            [
                'data' => [
                    'id' => 'edit_form',
                    'action' => $this->getUrl('*/*/save'),
                    'method' => 'post',
                ],
            ]
        );

        // 设置表单为容器
        $form->setUseContainer(true);
        $this->setForm($form);

        // 创建字段集
        $fieldset = $form->addFieldset(
            'base_fieldset',
            ['legend' => __('Item Information'), 'class' => 'fieldset-wide']
        );

        // 如果是编辑模式,添加隐藏字段
        if ($model->getId()) {
            $fieldset->addField(
                'item_id',
                'hidden',
                ['name' => 'item_id']
            );
        }

        // 添加“名称”字段
        $fieldset->addField(
            'name',
            'text',
            [
                'name' => 'name',
                'label' => __('Name'),
                'title' => __('Name'),
                'required' => true,
            ]
        );

        // 添加“描述”字段
        $fieldset->addField(
            'description',
            'textarea',
            [
                'name' => 'description',
                'label' => __('Description'),
                'title' => __('Description'),
                'required' => true,
            ]
        );

        // 添加“是否激活”字段
        $fieldset->addField(
            'is_active',
            'select',
            [
                'name' => 'is_active',
                'label' => __('Is Active'),
                'title' => __('Is Active'),
                'values' => [
                    ['value' => 1, 'label' => __('Yes')],
                    ['value' => 0, 'label' => __('No')],
                ],
            ]
        );

        // 设置表单的值
        if ($model->getId()) {
            $form->setValues($model->getData());
        }

        return parent::_prepareForm();
    }
}

表单页面通过这两个文件将被创建完成

9.显示测试

创建好所有的文件之后,打开admin后端登录进去,导航到content目录,就可以看到

HelloWorld Items的菜单页面,点击进入

如图就是新创建的items项目的列表页面,以及添加item的按钮,点击Add New Item按钮进去

这个就是edit表单提交的页面,可以通过填写表单信息,Sava Item进行提交,或者返回按钮返回上层列表页面。

表单提交完成之后在列表页就可以看到刚刚录入的Item信息,在Action列可以对指定数据进行删除修改操作。

以上就是完整的创建一个自定义模块来实现CRUD操作的具体操作以及文件,其中各种插件内容,以及功能可以自行进行尝试

下一篇将学习如何重写一个核心类的方法 Magento2.3.5学习重写核心类-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值