SAP UI5 应用的分页加载数据集,是一个极为重要的特性,需要 SAP UI5 前端和 OData 服务后端同时进行相应的开发工作,才能实现这个场景。
所谓分页加载数据集,就是默认情况下,SAP UI5 应用在启动后的默认页面里,只显示指定数据的数据集,这个个数默认为 20,也可以在系统或者代码里进行配置。因此我们可以理解成,SAP UI5 应用初始化时,默认从数据库加载第 1 到第 20 条数据。
当我们的滚动条向下滑动至屏幕底部时,会触发新一批数据的加载,读取第 21 条到第 40条也就是第二个 20 条数据。
SAP UI5 调用后台 OData 服务时,通过参数 $skip=X&$top=Y
来进行分页场景的指定。
-
其中
$skip=X
,代表跳过数据库第 X 条记录,从 X + 1 条记录开始读取(X为索引值,从 0 开始计数) -
$top=Y
,代表总共读取数据库 Y 条记录。
假设后台的 SAP ABAP OData 服务针对消费者通过 url 传入的 $skip=X&$top=Y
,已经正确实现,则 SAP UI5 应用,以分页的方式消费该 OData 服务,具体实现步骤,可以参考笔者这些文章:
-
SAP UI5 应用开发教程之九十二 - 基于 SAP UI5 JSONModel 客户端模型的列表分页显示(Table Pagination)前提
-
SAP UI5 应用开发教程之九十四 - 基于 JSONModel 数据模型的 SAP UI5 列表控件分页显示数据的完整解决方案
下面介绍为了支持分页加载数据集的 SAP ABAP OData 服务的后台实现。
首先我们构造带有分类加载数据集请求参数的 url:
https://{{host}}:{{port}}/sap/opu/odata/sap/ZBOOK_MANAGE_SRV/BookCollection?$skip=1&$top=2
意思是从数据库里第 2 条记录(因为 $skip 索引从1开始)开始读取,总共读取 2 条记录。
我们在图书管理 OData 服务的 Data Provider Class 的 GET_ENTITYSET 里设置断点,然后用 Postman 发送上述请求,观察这个方法的输入参数里包含的 skip 和 top 参数:
发现分别包含在 is_paging
结构体的 skip 和 top 参数里。
为了分页实现所作的增强,源代码如下所示,增加了一个 IF 分支。
如果 is_paging 输入参数不为空,说明 OData 服务消费者,指定了 top 等分页参数。
此时我们需要根据这两个整数值,从存储了数据库全部记录的内表 lt_book
里,摘取出部分子集数据。变量 lv_index 的初始值,维护了从数据库的第几条记录开始摘取。这个初始值等于用户输入参数 $skip
的值再加上 1,因为后者是从 0 开始索引计数的。
而 lv_read_count 是一个计数器,每当从 lt_book
内表里摘取一条记录出来之后,计数器就加一。显然,这个计数器的值,不能超过另一个分页参数 $top
的值。
下图是数据库表全部 4 条数据。
最后我们来做一个测试:
https://{{host}}:{{port}}/sap/opu/odata/sap/ZBOOK_MANAGE_SRV/BookCollection?$skip=1&$top=2
如上 url,语义是,从数据库第 2( top 值为 2) 条数据。
测试结果,确实数据库第 2 和第 3 条记录被 OData 请求返回了:
GET_ENTITYSET 的完全代码如下:
METHOD /iwbep/if_mgw_appl_srv_runtime~get_entityset.
DATA: lt_book_db TYPE TABLE OF zbooks,
ls_book_db LIKE LINE OF lt_book_db,
lt_book TYPE zcl_zbook_manage_mpc=>tt_book,
ls_book LIKE LINE OF lt_book,
ls_order LIKE LINE OF it_order,
ls_filter LIKE LINE OF it_filter_select_options,
ls_option LIKE LINE OF ls_filter-select_options.
FIELD-SYMBOLS: <book> LIKE lt_book.
IF it_filter_select_options IS INITIAL.
SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_book_db FROM zbooks.
LOOP AT lt_book_db INTO ls_book_db.
MOVE-CORRESPONDING ls_book_db TO ls_book.
APPEND ls_book TO lt_book.
ENDLOOP.
ELSE.
READ TABLE it_filter_select_options INTO ls_filter INDEX 1.
READ TABLE ls_filter-select_options INTO ls_option INDEX 1.
IF ls_filter-property = 'book_id' AND ls_option-option = 'EQ'.
SELECT SINGLE * INTO ls_book_db FROM zbooks WHERE book_id = ls_option-low.
MOVE-CORRESPONDING ls_book_db TO ls_book.
APPEND ls_book TO lt_book.
ENDIF.
ENDIF.
IF is_paging IS NOT INITIAL.
DATA: lv_index TYPE int4,
lv_read_count TYPE int4 VALUE 0,
lt_paged_table LIKE lt_book,
ls_line LIKE LINE OF lt_book.
lv_index = is_paging-skip + 1.
WHILE lv_read_count < is_paging-top.
READ TABLE lt_book INTO ls_line INDEX lv_index.
IF sy-subrc <> 0.
EXIT.
ENDIF.
APPEND ls_line TO lt_paged_table.
lv_read_count = lv_read_count + 1.
lv_index = lv_index + 1.
ENDWHILE.
lt_book = lt_paged_table.
ENDIF.
CREATE DATA er_entityset TYPE zcl_zbook_manage_mpc=>tt_book.
ASSIGN er_entityset->* TO <book>.
<book> = lt_book.
CHECK it_order IS NOT INITIAL.
READ TABLE it_order INTO ls_order INDEX 1.
IF ls_order-property <> 'author_name' AND ls_order-property <> 'book_name'.
RETURN.
ENDIF.
IF ls_order-order IS INITIAL OR ls_order-order = 'asc'.
SORT <book> BY (ls_order-property).
ELSEIF ls_order-order = 'desc'.
SORT <book> BY (ls_order-property) DESCENDING.
ENDIF.
ENDMETHOD.
网友评论