SAPUI5 (36) - OData Model 连接后端 SAP 系统 (下)

继续上一篇的内容,完成使用 OData Model 连接到后端 SAP 系统,实现 CRUD 操作。

程序界面:

点击 Create 按钮,弹出对话框:

输入 id, name 和 Address,点击 Save 按钮保存数据,点击 Cancel 按钮取消。

单击 table 中某行后,点击 Edit 按钮,弹出对话框:

可以进行修改操作。

单击 table 中某行后,点击 Delete 按钮,提示确认删除对话框,可以进行删除操作。

要点:

  • SAP Web IDE 实现代理
  • 配置数据源
  • 连接到 SAP 后端并实现 CRUD 操作

SAP Web IDE 代理配置

我使用的 IDE 是 Web IDE personal edition,如果把 Web IDE 的安装目录称作 webide_home 的话,我们需要在 webide_home\config_master\service.destinations\destinations 下配置连接,这个连接对于所有 Project 都可以使用。请参考本系列的第 33 篇。

本次我们连接的后端系统标识为 DPH,所以我们的配置文件名为 DPH,没有扩展名。配置文件的内容如下:

Description=DP Hana
Type=HTTP
TrustAll=true
Authentication=NoAuthentication
WebIDEUsage=odata_abap,dev_abap,ui5_execute_abap
Name=DPH
WebIDEEnabled=true
URL=HTTP\://dph01.nodomain\:8180
ProxyType=OnPremise
WebIDESystem=DPH
sap-client=100

配置数据源

在 SAP Web IDE 中,创建类型为 SAPUI5 Application 的项目,这种类型项目的文件结构相对来说是最简单的。创建完成后,项目的文件结构如下:

配置 neo-app.json 文件

在 neo-app.json 文件中,增加一项 path 配置,内容如下:

    {
      "path": "/sap/opu/odata",
      "target": {
        "type": "destination",
        "name": "DPH",
        "entryPath": "/sap/opu/odata"
      },
      "description": "DP Hana"
    }

配置 Application descriptor

Application descriptor 就是 webapp 下面的 manifest.json 文件,使用 App Descriptor Editor 打开,切换到 Data Sources 页签,点击 “+” 号来添加一个数据源:

系统弹出对话框简化配置,切换到 Service URL,选择在前面配置的 SAP 连接,第一行 DP Hana 保存的是 domain 信息,第二行配置的是 service url 的 path:

点击 Test 按钮,提示输入用户名和密码,如果一切 OK, 系统读取到 OData service 并且加载:

选中 EmployeeCollection ,点击 Next 按钮即可完成配置。

metadata.xml 文件会被配置到 model 文件夹下面。但我的 Web IDE 版本将实际文件放在 localServices 文件夹下面,需要手工调整位置。这个文件也可以通过在浏览器中 $metadata 参数的方法得到。

然后在 manifest.json 文件中增加默认 model 为刚才配置的 data source:

"sap.ui5": {
		"_version": "1.1.0",
		"rootView": {
			"viewName": "zui5_odata_sap_crud.view.App",
			"type": "XML"
		},
		"dependencies": {
			"minUI5Version": "1.30.0",
			"libs": {
				"sap.ui.core": {},
				"sap.m": {},
				"sap.ui.layout": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "zui5_odata_sap_crud.i18n.i18n"
				}
			},
			"": {
				"dataSource": "zempprj_srv",
				"settings": {
					"metadataUrlParams": {
						"sap-documentation": "heading"
					}
				}
			}
		},
		"resources": {
			"css": [{
				"uri": "css/style.css"
			}]
		}
	}

此时运行程序,应该会提示输入用户名和密码,表示数据源配置成功。

界面设置

主界面

因为不打算使用 routing,直接在 root view ,即 App.view.xml 文件中设置主要的 UI 元素:

<mvc:View xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
	controllerName="zui5_odata_sap_backend_crud.controller.App">
	<App>
		<pages>
			<Page title="{i18n>title}">
				<content>
					<Table noDataText="No data" id="idTable" items="{path:'/EmployeeCollection'}">
						<items>
							<ColumnListItem type="Navigation" press="onItemPress">
								<cells>
									<Text text="{EmpId}"/>
									<Text text="{EmpName}"/>
									<Text text="{EmpAddr}"/>
								</cells>
							</ColumnListItem>
						</items>
						<columns>
							<Column id="EmpIdCol">
								<header>
									<Label text="Employee ID"/>
								</header>
							</Column>
							<Column id="EmpNameCol">
								<header>
									<Label text="Name"/>
								</header>
							</Column>
							<Column id="EmpAddrCol">
								<header>
									<Label text="Address"/>
								</header>
							</Column>
						</columns>
					</Table>
				</content>
				<footer>
					<Bar>
						<contentRight>
							<Button icon="sap-icon://create" text="Create" press="onCreate"/>
							<Button icon="sap-icon://edit" text="Edit" press="onEdit"/>
							<Button icon="sap-icon://delete" text="Delete" press="onDelete"/>
						</contentRight>
					</Bar>
				</footer>
			</Page>
		</pages>
	</App>
</mvc:View>

对话框

<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:f="sap.ui.layout.form">
	
	<Dialog id="employeeDialog" title="Employee CRUD">
		<f:SimpleForm>
			<Label text="Employee Id"/>
			<Input id="EmpId" value="{EmpId}"/>
			<Label text="Name"/>
			<Input id="EmpName" value="{EmpName}"/>
			<Label text="Address"/>
			<Input id="EmpAddr" value="{EmpAddr}"/>
		</f:SimpleForm>
		<Toolbar>
			<ToolbarSpacer/>
			<Button id="SaveCreate" text="Save"/>
			<Button id="SaveEdit" text="Save Edit"/>
			<Button id="CancelButton" text="Cancel" />
		</Toolbar>
	</Dialog>
	
</core:FragmentDefinition>

控制器代码

主要的代码都在 App.controller.js 中,先给出完整代码:

sap.ui.define([
	"sap/ui/core/mvc/Controller"
], function(Controller) {
	"use strict";

	var oModel;
	var sCurrentPath; // current path
	var sCurrentEmp; // cureent employee

	return Controller.extend("zui5_odata_sap_backend_crud.controller.App", {

		onInit: function() {
			oModel = this.getOwnerComponent().getModel();
			oModel.setUseBatch(false);
			this.getView().setModel(oModel);
		},

		openDialog: function() {
			var oView = this.getView();

			// Open dialog
			var oEmpDialog = oView.byId("employeeDialog");
			if (!oEmpDialog) {
				oEmpDialog = sap.ui.xmlfragment(oView.getId(),
					"zui5_odata_sap_backend_crud.view.EmployeeDialog");
				oView.addDependent(oEmpDialog);
			}

			oEmpDialog.open();

			// Attach press event for CancelButton
			var oCancelButton = oView.byId("CancelButton");
			oCancelButton.attachPress(function() {
				oEmpDialog.close();
			});
		},

		// onCreate event
		onCreate: function() {
			var oView = this.getView();

			this.openDialog();
			var oEmployeeDialog = oView.byId("employeeDialog");
			oEmployeeDialog.setTitle("Create Employee");
			oView.byId("EmpId").setEditable(true);
			oView.byId("SaveEdit").setVisible(false);
			oView.byId("SaveCreate").setVisible(true);

			// clear
			oView.byId("EmpId").setValue("");
			oView.byId("EmpName").setValue("");
			oView.byId("EmpAddr").setValue("");

			// commit save
			oView.byId("SaveCreate").attachPress(function() {
				var oNewEntry = {
					"Mandt": "100",
					"EmpId": "",
					"EmpName": "",
					"EmpAddr": ""
				};

				// populate value from form
				oNewEntry.EmpId = oView.byId("EmpId").getValue();
				oNewEntry.EmpName = oView.byId("EmpName").getValue();
				oNewEntry.EmpAddr = oView.byId("EmpAddr").getValue();

				// Commit creation operation
				oModel.create("/EmployeeCollection", oNewEntry, {
					success: function() {
						sap.m.MessageToast.show("Created successfully.");
					},
					error: function(oError) {
						window.console.log("Error", oError);
					}
				});

				// close dialog
				if (oEmployeeDialog) {
					oEmployeeDialog.close();
				}
			});
		},

		onEdit: function() {
			// no employee was selected
			if (!sCurrentEmp) {
				sap.m.MessageToast.show("No Employee was selected.");
				return;
			}

			var oView = this.getView();

			this.openDialog();
			var oEmployeeDialog = oView.byId("employeeDialog");
			oEmployeeDialog.setTitle("Edit Employee");
			oView.byId("EmpId").setEditable(false);
			oView.byId("SaveEdit").setVisible(true);
			oView.byId("SaveCreate").setVisible(false);

			// populate fields
			oView.byId("EmpId").setValue(oModel.getProperty(sCurrentPath + "/EmpId"));
			oView.byId("EmpName").setValue(oModel.getProperty(sCurrentPath + "/EmpName"));
			oView.byId("EmpAddr").setValue(oModel.getProperty(sCurrentPath + "/EmpAddr"));

			// Attach save event
			oView.byId("SaveEdit").attachPress(function() {
				var oChanges = {
					"Mandt": "100",
					"EmpName": "",
					"EmpAddr": ""
				};

				// populate value from form
				oChanges.EmpName = oView.byId("EmpName").getValue();
				oChanges.EmpAddr = oView.byId("EmpAddr").getValue();

				// commit creation
				oModel.update(sCurrentPath, oChanges, {
					success: function() {
						sap.m.MessageToast.show("Changes were saved successfully.");
					},
					error: function(oError) {
						window.console.log("Error", oError);
					}
				});

				// close dialog
				if (oEmployeeDialog) {
					oEmployeeDialog.close();
				}
			});
		},

		// onDelete event
		onDelete: function() {
			var that = this;

			// no employee was selected
			if (!sCurrentEmp) {
				sap.m.MessageToast.show("No Employee was selected.");
				return;
			}

			var oDeleteDialog = new sap.m.Dialog();
			oDeleteDialog.setTitle("Deletion");

			var oText = new sap.m.Label({
				text: "Are you sure to delete employee [" + sCurrentEmp + "]?"
			});
			oDeleteDialog.addContent(oText);

			oDeleteDialog.addButton(
				new sap.m.Button({
					text: "Confirm",
					press: function() {
						that.deleteEmployee();
						oDeleteDialog.close();
					}
				})
			);

			oDeleteDialog.open();
		},

		// deletion operation
		deleteEmployee: function() {
			oModel.remove(sCurrentPath, {
				success: function() {
					sap.m.MessageToast.show("Deletion successful.");
				},
				error: function(oError) {
					window.console.log("Error", oError);
				}
			});
		},

		onItemPress: function(evt) {
			var oContext = evt.getSource().getBindingContext();
			sCurrentPath = oContext.getPath();
			sCurrentEmp = oContext.getProperty("EmpName");
		}
	});
});

要点说明:

Model

我们使用的是 OData Model,但是并没有任何代码来显示申明。OData Model 的声明来自 manifest.json。根据 OpenUI5 SDK,如果 DataSource 为 OData,没有指定 type,则默认的 type 为 OData v2,这正是我们想要的。

然后在 Controller 的 onInit 事件中绑定 view 和 model:

onInit: function() {
    oModel = this.getOwnerComponent().getModel();
    oModel.setUseBatch(false);
    this.getView().setModel(oModel);
}

新增记录 ( create )

var oNewEntry = {
    "Mandt": "100",
    "EmpId": "",
    "EmpName": "",
    "EmpAddr": ""
};

// populate value from form
oNewEntry.EmpId = oView.byId("EmpId").getValue();
oNewEntry.EmpName = oView.byId("EmpName").getValue();
oNewEntry.EmpAddr = oView.byId("EmpAddr").getValue();

// Commit creation operation
oModel.create("/EmployeeCollection", oNewEntry, {
    success: function() {
        sap.m.MessageToast.show("Created successfully.");
    },
    error: function(oError) {
        window.console.log("Error", oError);
    }
});

修改记录

var oChanges = {
    "Mandt": "100",
    "EmpName": "",
    "EmpAddr": ""
};

// populate value from form
oChanges.EmpName = oView.byId("EmpName").getValue();
oChanges.EmpAddr = oView.byId("EmpAddr").getValue();

// commit creation
oModel.update(sCurrentPath, oChanges, {
    success: function() {
        sap.m.MessageToast.show("Changes were saved successfully.");
    },
    error: function(oError) {
        window.console.log("Error", oError);
    }
});

删除记录

deleteEmployee: function() {
    oModel.remove(sCurrentPath, {
        success: function() {
            sap.m.MessageToast.show("Deletion successful.");
        },
        error: function(oError) {
            window.console.log("Error", oError);
        }
    });
}

源码

36_01_zui5_odata_sap_backend_crud
36_02_zui5_odata_sap_backend_crud

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值