通过 OData 模型创建新实体

学习目标

  • 通过 SAPUI5 OData 模型为 OData 服务创建新实体

批处理控制

组 ID

OData V4 模型在以下情况下发送请求:

  • 隐式读取请求,用于检索绑定的数据 例如,具有绝对路径 /UX_Customer 的列表绑定会触发 GET UX_Customer 来读取数据。

  • 通过双向绑定发起的隐式更新请求 例如,通过相对路径为 CustomerName 的属性绑定更新客户名称,该绑定具有路径为 /UX_Customer(00505604-4e85-1edd-818f-21e64b9cd2cf) 的上下文,从而触发 PATCH UX_Customer(00505604-4e85-1edd-818f-21e64b9cd2cf),并以客户名称的值作为 JSON 负载。

  • 通过 API 调用(如 ODataListBinding.refresh()ODataContextBinding.execute())触发的显式请求

对于上述每种情况,都可以指定 string 类型的 Group ID,以便将多个操作分组到单个 HTTP 请求负载(批处理请求)中。

OData 批处理请求使用 Group ID: 表示自动批处理, 表示直接发送,开发者定义的 Application Group ID 表示自定义批处理。

Group ID 具有以下提交模式之一,用于控制批处理请求的使用:

  • sap.ui.model.odata.v4.SubmitMode.API 与此提交模式关联的请求通过 sap.ui.model.odata.v4.ODataModel#submitBatch() 以批处理请求的方式发送。

  • sap.ui.model.odata.v4.SubmitMode.Auto 与此提交模式关联的请求以批处理请求的方式发送,该批处理请求会在渲染前自动触发。

  • sap.ui.model.odata.v4.SubmitMode.Direct 与此提交模式关联的请求会直接发送,不使用批处理。

可以使用以下 Group ID

  • $auto$auto.* 预定义的批处理 Group ID,在未指定 Group ID 时这是默认值。你可以使用不同的 $auto.*Group ID 来使用不同的批处理请求。后缀可以是任意非空字符串,由基本拉丁字母表中的字母数字字符(包括下划线)组成。它们的提交模式为 sap.ui.model.odata.v4.SubmitMode.Auto

  • $direct 预定义的批处理 Group ID,其提交模式为 sap.ui.model.odata.v4.SubmitMode.Direct

  • Application Group IDs Application Group ID 是一个非空字符串,由基本拉丁字母表中的字母数字字符(包括下划线)组成。默认情况下,Application Group ID 的提交模式为 sap.ui.model.odata.v4.SubmitMode.API。 在构造 OData 模型时,可以为 Application Group IDs 定义不同的提交模式。当你想把需要在服务器上处理时间较短的请求与处理时间较长的请求分开时,这会很有用,这样 "fast" 请求的响应就能更早地在 UI 上可见。

在 XML 视图中使用组 ID

要为隐式请求指定 Group ID,请为绑定使用以下参数:$$updateGroupId – 更新请求的 Group ID

在图中 Usage of Group IDs in XML Views 所示的示例中,表单的绑定上下文通过 <SimpleForm> 标签的 binding 属性设置为 /UX_Customer(00505604-4e85-1edd-818f-21e64b9cd2cf)。此外,读取和更新请求的 Group ID 设置为 $direct$$updateGroupId$$groupId 参数)。因此,表单的数据(即 Id 为 00505604-4e85-1edd-818f-21e64b9cd2cf 的客户的名称和城市)会直接读取而不使用批处理。同样,通过双向绑定对名称和城市所做的更新也会直接发送而不使用批处理。

OData 模型的 Group ID 默认值为 $autoGroup ID 的值会用作 OData 模型 Update Group ID 的默认值。

在实例化 OData 模型时,你还可以同时提供 Group IDUpdate Group ID;如果指定了这些值,则在未显式设置相应的绑定参数时,它们会用作默认值。

对于显式请求,可以将 Group ID 指定为相应 API 方法的可选参数。绑定的 Group IDUpdate Group ID 会用作默认值。

创建实体

在图中 Creating an Entity - Example 所示的示例中,当按下 UI 上的 Create Customer 按钮时会创建一个新客户。

sap.ui.model.odata.v4.ODataListBinding#create 创建一个新实体。创建新实体时使用绑定的 Update Group ID。sap.ui.model.odata.v4.Context#created 返回一个 Promise,当实体已在后端创建完成时该 Promise 会得到解决。

示例应用程序在 UI 上使用一个 Id 为 customerTable 的表格,通过其 items 聚合显示客户实体集。对于该实体集,需要创建一个新实体。

Create Customer 按钮的事件处理程序中使用 getBinding 方法查询 UI 表格 items 聚合的绑定对象。该绑定对象的类型为 sap.ui.model.odata.v4.ODataListBinding。该列表绑定的 create 方法会创建一个新的客户实体,并将其插入到列表的开头。该方法会接收要创建的实体的数据。编码示例中未展示客户数据。例如,它可以来自用户已填写的表单。

创建新实体时使用列表绑定的 Update Group ID。在示例中,列表绑定既未显式设置 $$groupId 参数,也未显式设置 $$updateGroupId 参数,因此默认情况下,创建操作使用 $autoUpdate Group ID。也就是说,客户会通过相应的批处理请求在后端中创建,该请求会在渲染前自动触发。

create 方法返回新创建实体的上下文对象。它的类型为 sap.ui.model.odata.v4.Context。该上下文对象的 created 方法返回一个 promise,当该上下文所表示的实体已在后端创建完成时,该 promise 会不带数据地得到解决。为这种情况注册的函数例如可用于显示成功消息。

实现 OData 创建操作

业务场景

按下 Overview 视图上的 Create Customer 按钮时,目前会弹出一个弹出窗口,其中显示信息文本,说明客户稍后将通过 OData 服务创建。在本练习中,你将实现该创建操作。为此,你将首先删除弹出窗口的实现以及其中使用的信息文本。然后,你将重新实现 Create Customer 按钮的事件处理程序方法,以便通过已集成在应用程序中的 OData 服务创建新客户。*模板:*Git Repository: https://github.com/SAP-samples/sapui5-development-learning-journey.git, Branch: **sol/20_OData_model_(read)***参考答案:*Git Repository: https://github.com/SAP-samples/sapui5-development-learning-journey.git, Branch: sol/21_OData_model_(create)

任务 1:删除弹出窗口的实现以及所使用的信息文本

步骤

  1. 弹出窗口的实现位于 *Dialog.fragment.xml* 文件中。从 *webapp/view* 文件夹中删除该文件。

  2. 在项目树中打开 *Dialog.fragment.xml* 文件的上下文菜单。

  3. 选择 Delete Permanently

  4. 在对话框中通过选择 Delete 进行确认。

  5. 在编辑器中打开 *i18n* 文件夹中的 *i18n.properties* 资源束文件。

  6. 从文件中删除以下现已不再需要的键值对:

# Fragment
dialogText=Customer {0} is later saved via an OData service.

任务 2:按下按钮时通过 OData 服务创建新客户

步骤

  1. 在接下来的步骤中,你将实现通过 OData 服务创建新客户。在此过程中,成功时会在 UI 上显示一条相应的可翻译消息。为此,请在 *i18n.properties* 资源束文件中创建以下键值对:

customerCreatedMessage=Customer successfully created

结果

i18n.properties 资源束文件现在应如下所示: i18n.properties 文件的屏幕截图。 2. 现在,在编辑器中打开 *webapp/controller* 文件夹中的 *Overview.controller.js* 文件。 3. 上面创建的成功消息将通过消息提示(message toast)显示在 UI 上。为此,请将 sap/m/MessageToast 模块添加到视图控制器的依赖项数组,并向工厂函数添加一个名为 MessageToast 的相应参数。

结果

视图控制器现在应如下所示: Overview.controller.js 文件,突出显示了 sap/m/MessageToast 属性。 4. 将 onSave 事件处理程序方法的当前实现替换为以下编码:

var oModelData = this.getView().getModel("customer").getData();
var oResourceBundle = this.getView().getModel("i18n").getResourceBundle();
if (oModelData.Discount === undefined) { oModelData.Discount = 0; }
this.byId("customerTable").getBinding("items").create({
"Form": oModelData.Form,
"CustomerName": oModelData.CustomerName,
"Discount": oModelData.Discount + "",
"Street": oModelData.Street,
"PostCode": oModelData.PostCode,
"City": oModelData.City,
"Country": oModelData.Country,
"Email": oModelData.Email,
"Telephone": oModelData.Telephone
}).created().then(function () {
MessageToast.show(oResourceBundle.getText("customerCreatedMessage"));
});

注意

该编码使用表单中输入的数据创建一个新的客户实体。创建完成后,来自资源束的成功消息会作为消息提示显示。

结果

onSave 事件处理程序方法现在应如下所示: Overview.controller.js 文件,突出显示了 onSave 函数。 5. 通过从 SAP Business Application Studio 启动应用程序来进行测试运行。

警告

与上一个练习一样,测试时不会在后端系统中调用 OData 服务。而是通过 mock server 模拟对远程系统的访问。为此,请使用名为 start-mock 的 npm 脚本启动应用程序,而不是之前使用的 start-noflp 脚本。 确保按下 Create Customer 按钮时,会使用表单中输入的数据创建新客户。成功消息应作为消息提示出现,并且该客户应自动添加到客户表格中。 注意

请注意,客户数据并不会真正通过 mock server 持久化保存。也就是说,如果你重新启动应用程序,所有新建的客户都会丢失。(另请注意,如果你连接到后端系统,数据将会持久化保存在该系统中。)

  1. 右键单击你的 sapui5-development-learning-journey 项目中的任意子文件夹,然后在出现的上下文菜单中选择 Preview Application

  2. 在出现的对话框中选择名为 start-mock 的 npm 脚本。

  3. 在打开的应用程序中,检查组件是否按预期工作。