之前学习了如果创建一个简单的模块,包括创建目录结构,定义模块,创建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博客