{ Hello Magento 2 }

解决 Magento 2 应用问题,更注重深度挖掘。(ง •̀_•́)ง

0%

How to Create Admin Grid in Magento 2

Admin Grid 是一种表格,用来展示数据库表中的记录,附带一些额外的特性:排序、筛选、删除更新等。Admin Grid 的创建有两种方式:使用 layout 和使用 component 。本篇是利用 component 创建的 Admin Grid 。 文章中涉及的内容太多了,还有很多地方可以分解和完善,先发出来,作为初探,或者是索引以供后续研究。

前提

ThankIT_HelloWorld 模块为基础,已经通过 InstallSchema 添加了数据表,创建了 Admin Menu 和 ACL 如果没有,参考以下文章: CRUD Models in Magento 2 Magento 2 Create Admin Menu Magento 2 Admin ACL Access Control Lists 我们的 admin menu 创建了一个后台 path

1
thankit_helloworld/post/index

创建 routes.xml

File: app\code\ThankIT\HelloWorld\etc\adminhtml\routes.xml

1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
<router id="admin">
<route id="thankit_helloworld" frontName="thankit_helloworld">
<module name="ThankIT_HelloWorld" after="Magento_Backend"/>
</route>
</router>
</config>

创建 controller

File:app\code\ThankIT\HelloWorld\Controller\Adminhtml\Post\Index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
namespace ThankIT\HelloWorld\Controller\Adminhtml\Post;

class Index extends \Magento\Backend\App\Action
{
const ADMIN_RESOURCE = 'ThankIT_HelloWorld::post';
protected $resultPageFactory;
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}

public function execute()
{
$page = $this->resultPageFactory->create();
// var_dump(get_class($page));
// 'Magento\Backend\Model\View\Result\Page\Interceptor' (length=50)
// 如果没有下面这句,title 是 Magento Admin ,active menu 正常
// 如果下面这句的 id 不存在,则 active menu 不正常 title 还是 Magento Admin
$page->setActiveMenu('ThankIT_HelloWorld::post');
// title 替换成 Posts
$page->getConfig()->getTitle()->prepend((__('Posts')));

// class: Magento\Backend\Model\View\Result\Page
// addBreadcrumb($label, $title, $link = null)
$page->addBreadcrumb(__('ThankIT'), __('ThankIT'));
$page->addBreadcrumb(__('Hello World'), __('Manage Blogs'));
return $page;
}

}

创建 layout

File: app\code\ThankIT\HelloWorld\view\adminhtml\layout\thankit_helloworld_post_index.xml

1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<update handle="styles"/>
<body>
<referenceContainer name="content">
<uiComponent name="thankit_helloworld_post_listing"/>
</referenceContainer>
</body>
</page>

注意我们这里声明的 uiComponent name="thankit_helloworld_post_listing"

创建 component layout file

File:app/code/ThankIT/HelloWorld/view/adminhtml/ui_component/thankit_helloworld_post_listing.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<?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">
<item name="provider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing_data_source</item>
<item name="deps" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing_data_source</item>
</item>
<item name="spinner" xsi:type="string">thankit_helloworld_post_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 Post</item>
<item name="class" xsi:type="string">primary</item>
<item name="url" xsi:type="string">*/*/new</item>
</item>
</item>
</argument>
<dataSource name="thankit_helloworld_post_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<!-- <argument name="class" xsi:type="string">ThankITHelloWorldPostGridDataProvider</argument> -->
<argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument>
<argument name="name" xsi:type="string">thankit_helloworld_post_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">post_id</argument>
<argument name="requestFieldName" xsi:type="string">post_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="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">thankit_helloworld_post_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">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_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>
<exportButton name="export_button">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="selectProvider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns.ids</item>
</item>
</argument>
</exportButton>
<filterSearch name="fulltext">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="provider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing_data_source</item>
<item name="chipsProvider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.listing_top.listing_filters_chips</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.search</item>
</item>
</item>
</argument>
</filterSearch>
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsProvider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_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">thankit_helloworld_post_listing.thankit_helloworld_post_listing.listing_top.listing_filters</item>
<item name="imports" xsi:type="array">
<item name="visible" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns.${ $.index }:visible</item>
</item>
</item>
</item>
<item name="observers" xsi:type="array">
<item name="column" xsi:type="string">column</item>
</item>
</argument>
</filters>
<massaction name="listing_massaction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="selectProvider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns.ids</item>
<item name="indexField" xsi:type="string">post_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="thankit_helloworld/post/massDelete"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Delete Posts</item>
<item name="message" xsi:type="string" translate="true">Are you sure you wan't to delete selected Posts?</item>
</item>
</item>
</argument>
</action>
<action name="edit">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="type" xsi:type="string">edit</item>
<item name="label" xsi:type="string" translate="true">Edit</item>
<item name="callback" xsi:type="array">
<item name="provider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns_editor</item>
<item name="target" xsi:type="string">editSelected</item>
</item>
</item>
</argument>
</action>
</massaction>
<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">thankit_helloworld_post_listing.thankit_helloworld_post_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.paging</item>
</item>
<item name="selectProvider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns.ids</item>
</item>
</argument>
</paging>
</container>
<columns name="thankit_helloworld_post_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">thankit_helloworld_post_listing.thankit_helloworld_post_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current</item>
</item>
<item name="editorConfig" xsi:type="array">
<item name="selectProvider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns.ids</item>
<item name="enabled" xsi:type="boolean">true</item>
<item name="indexField" xsi:type="string">post_id</item>
<item name="clientConfig" xsi:type="array">
<item name="saveUrl" xsi:type="url" path="thankit_helloworld/post/inlineEdit"/>
<item name="validateBeforeSave" xsi:type="boolean">false</item>
</item>
</item>
<item name="childDefaults" xsi:type="array">
<item name="fieldAction" xsi:type="array">
<item name="provider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns_editor</item>
<item name="target" xsi:type="string">startEdit</item>
<item name="params" xsi:type="array">
<item name="0" xsi:type="string">${ $.$data.rowIndex }</item>
<item name="1" xsi:type="boolean">true</item>
</item>
</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.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>
</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">post_id</item>
</item>
</argument>
</selectionsColumn>
<column name="post_id">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">textRange</item>
<item name="sorting" xsi:type="string">asc</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="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Name</item>
</item>
</argument>
</column>
<column name="url_key">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="visible" xsi:type="boolean">false</item>
<item name="label" xsi:type="string" translate="true">URL Key</item>
<item name="dataType" xsi:type="string">text</item>
</item>
</argument>
</column>
<column name="tags">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="visible" xsi:type="boolean">false</item>
<item name="label" xsi:type="string" translate="true">Tags</item>
<item name="dataType" xsi:type="string">text</item>
</item>
</argument>
</column>
<column name="status">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">Magento\Config\Model\Config\Source\Yesno</item>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">select</item>
<item name="label" xsi:type="string" translate="true">Status</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
<item name="dataType" xsi:type="string">select</item>
</item>
</argument>
</column>
<column name="sample_country_selection">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">Magento\Config\Model\Config\Source\Locale\Country</item>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">select</item>
<item name="visible" xsi:type="boolean">false</item>
<item name="label" xsi:type="string" translate="true">Sample Country Selection</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
<item name="dataType" xsi:type="string">select</item>
</item>
</argument>
</column>
<column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">dateRange</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
<item name="dataType" xsi:type="string">date</item>
<item name="label" xsi:type="string" translate="true">Created</item>
</item>
</argument>
</column>
<column name="updated_at" class="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">dateRange</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
<item name="dataType" xsi:type="string">date</item>
<item name="label" xsi:type="string" translate="true">Modified</item>
</item>
</argument>
</column>
<actionsColumn name="actions" class="ThankIT\HelloWorld\Ui\Component\Listing\Column\PostActions">
<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">post_id</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">thankit_helloworld_post_listing.thankit_helloworld_post_listing.listing_top</item>
<item name="listingProvider" xsi:type="string">thankit_helloworld_post_listing.thankit_helloworld_post_listing.thankit_helloworld_post_columns</item>
</item>
</argument>
</container>
</listing>

代码比较长,一段一段来分析。 我们在 layout 中声明的 listing name 是 thankit_helloworld_post_listing thankit-helloworld-post-listing.png 这里面经常用到的有四个元素,<argument>,<dataSource>,<columns>,<container>,这几个元素间的粗略关系见上图。 这个里面声明了一个 dataSource thankit_helloworld_post_listing_data_source

di.xml

File: app\code\ThankIT\HelloWorld\etc\di.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="thankit_helloworld_post_listing_data_source" xsi:type="string">ThankIT\HelloWorld\Model\ResourceModel\Post\Grid\Collection</item>
</argument>
</arguments>
</type>
<type name="ThankIT\HelloWorld\Model\ResourceModel\Post\Grid\Collection">
<arguments>
<argument name="mainTable" xsi:type="string">thankit_helloworld_post</argument>
<argument name="eventPrefix" xsi:type="string">thankit_helloworld_post_grid_collection</argument>
<argument name="eventObject" xsi:type="string">post_grid_collection</argument>
<argument name="resourceModel" xsi:type="string">ThankIT\HelloWorld\Model\ResourceModel\Post</argument>
</arguments>
</type>
<!-- start 这一段可以不要 -->
<!-- <virtualType name="ThankITHelloWorldPostGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
<arguments>
<argument name="collection" xsi:type="object" shared="false">ThankIT\HelloWorld\Model\ResourceModel\Post\Collection</argument>
<argument name="filterPool" xsi:type="object" shared="false">ThankITHelloWorldGirdFilterPool</argument>
</arguments>
</virtualType>
<virtualType name="ThankITHelloWorldGirdFilterPool" 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> -->
<!-- end 这一段可以不要 -->
</config>

其中重要部分如下图: di.xml

Grid Collection

File: ThankIT\HelloWorld\Model\ResourceModel\Post\Grid\Collection;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
namespace ThankIT\HelloWorld\Model\ResourceModel\Post\Grid;

class Collection extends \ThankIT\HelloWorld\Model\ResourceModel\Post\Collection implements \Magento\Framework\Api\Search\SearchResultInterface
{
/**
* Aggregations
*
* @var \Magento\Framework\Search\AggregationInterface
*/
protected $_aggregations;

/**
* constructor
*
* @param \Magento\Framework\Data\Collection\EntityFactoryInterface $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 $connection
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource
*/
public function __construct(
\Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
\Magento\Framework\Event\ManagerInterface $eventManager,
$mainTable,
$eventPrefix,
$eventObject,
$resourceModel,
$model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
$connection = null,
\Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
) {
parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
$this->_eventPrefix = $eventPrefix;
$this->_eventObject = $eventObject;
$this->_init($model, $resourceModel);
$this->setMainTable($mainTable);
}

/**
* @return \Magento\Framework\Search\AggregationInterface
*/
public function getAggregations()
{
return $this->_aggregations;
}

/**
* @param \Magento\Framework\Search\AggregationInterface $aggregations
* @return $this
*/
public function setAggregations($aggregations)
{
$this->_aggregations = $aggregations;
}

/**
* Retrieve all ids for collection
* Backward compatibility with EAV collection
*
* @param int $limit
* @param int $offset
* @return array
*/
public function getAllIds($limit = null, $offset = null)
{
return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams);
}

/**
* Get search criteria.
*
* @return \Magento\Framework\Api\SearchCriteriaInterfacenull
*/
public function getSearchCriteria()
{
return null;
}

/**
* Set search criteria.
*
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null)
{
return $this;
}

/**
* Get total count.
*
* @return int
*/
public function getTotalCount()
{
return $this->getSize();
}

/**
* Set total count.
*
* @param int $totalCount
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setTotalCount($totalCount)
{
return $this;
}

/**
* Set items list.
*
* @param \Magento\Framework\Api\ExtensibleDataInterface[] $items
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setItems(array $items = null)
{
return $this;
}
}

这部分参考的是 Magento\Cms\Model\ResourceModel\Page\Grid\Collection.php 还可以参考 Magento_Customer, Magento_Sales, Magento_CMS 这些模块。

验证结果

刷新缓存后,后台访问 Posts 链接 posts

参考文档

How to Create Admin Grid in Magento 2