美文网首页
SAPUI5 (36) - OData Model 连接后端 S

SAPUI5 (36) - OData Model 连接后端 S

作者: Stone0823 | 来源:发表于2017-05-09 23:12 被阅读880次

    继续上一篇的内容,完成使用 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

    参考资料

    相关文章

      网友评论

          本文标题:SAPUI5 (36) - OData Model 连接后端 S

          本文链接:https://www.haomeiwen.com/subject/wrcbtxtx.html