SAPUI5 (36) - OData Model 連接后端 SAP 系統(tǒng) (下)

繼續(xù)上一篇的內(nèi)容圆兵,完成使用 OData Model 連接到后端 SAP 系統(tǒng)尝苇,實現(xiàn) CRUD 操作蒸辆。

程序界面:

點擊 Create 按鈕治拿,彈出對話框:

輸入 id, name 和 Address足绅,點擊 Save 按鈕保存數(shù)據(jù)捷绑,點擊 Cancel 按鈕取消韩脑。

單擊 table 中某行后,點擊 Edit 按鈕粹污,彈出對話框:

可以進(jìn)行修改操作段多。

單擊 table 中某行后,點擊 Delete 按鈕壮吩,提示確認(rèn)刪除對話框衩匣,可以進(jìn)行刪除操作。

要點:

  • SAP Web IDE 實現(xiàn)代理
  • 配置數(shù)據(jù)源
  • 連接到 SAP 后端并實現(xiàn) CRUD 操作

SAP Web IDE 代理配置

我使用的 IDE 是 Web IDE personal edition粥航,如果把 Web IDE 的安裝目錄稱作 webide_home 的話琅捏,我們需要在 webide_home\config_master\service.destinations\destinations 下配置連接,這個連接對于所有 Project 都可以使用递雀。請參考本系列的第 33 篇柄延。

本次我們連接的后端系統(tǒng)標(biāo)識為 DPH,所以我們的配置文件名為 DPH缀程,沒有擴(kuò)展名搜吧。配置文件的內(nèi)容如下:

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

配置數(shù)據(jù)源

在 SAP Web IDE 中,創(chuàng)建類型為 SAPUI5 Application 的項目杨凑,這種類型項目的文件結(jié)構(gòu)相對來說是最簡單的滤奈。創(chuàng)建完成后,項目的文件結(jié)構(gòu)如下:

配置 neo-app.json 文件

在 neo-app.json 文件中撩满,增加一項 path 配置蜒程,內(nèi)容如下:

    {
      "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 頁簽昭躺,點擊 “+” 號來添加一個數(shù)據(jù)源:

系統(tǒng)彈出對話框簡化配置,切換到 Service URL伪嫁,選擇在前面配置的 SAP 連接领炫,第一行 DP Hana 保存的是 domain 信息,第二行配置的是 service url 的 path:

點擊 Test 按鈕张咳,提示輸入用戶名和密碼帝洪,如果一切 OK, 系統(tǒng)讀取到 OData service 并且加載:

選中 EmployeeCollection ,點擊 Next 按鈕即可完成配置脚猾。

metadata.xml 文件會被配置到 model 文件夾下面葱峡。但我的 Web IDE 版本將實際文件放在 localServices 文件夾下面,需要手工調(diào)整位置婚陪。這個文件也可以通過在瀏覽器中 $metadata 參數(shù)的方法得到族沃。

然后在 manifest.json 文件中增加默認(rèn) 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"
            }]
        }
    }

此時運行程序,應(yīng)該會提示輸入用戶名和密碼泌参,表示數(shù)據(jù)源配置成功脆淹。

界面設(shè)置

主界面

因為不打算使用 routing,直接在 root view 沽一,即 App.view.xml 文件中設(shè)置主要的 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烘嘱。根據(jù) OpenUI5 SDK,如果 DataSource 為 OData蝗蛙,沒有指定 type蝇庭,則默認(rèn)的 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

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哮内,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子壮韭,更是在濱河造成了極大的恐慌北发,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喷屋,死亡現(xiàn)場離奇詭異琳拨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)屯曹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門狱庇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人恶耽,你說我怎么就攤上這事僵井。” “怎么了驳棱?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵批什,是天一觀的道長。 經(jīng)常有香客問我社搅,道長驻债,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任形葬,我火速辦了婚禮合呐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘笙以。我一直安慰自己淌实,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拆祈,像睡著了一般恨闪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上放坏,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天咙咽,我揣著相機(jī)與錄音,去河邊找鬼淤年。 笑死钧敞,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的麸粮。 我是一名探鬼主播溉苛,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弄诲!你這毒婦竟也來了愚战?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤威根,失蹤者是張志新(化名)和其女友劉穎凤巨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洛搀,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡敢茁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了留美。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彰檬。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖谎砾,靈堂內(nèi)的尸體忽然破棺而出逢倍,到底是詐尸還是另有隱情,我是刑警寧澤景图,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布较雕,位于F島的核電站,受9級特大地震影響挚币,放射性物質(zhì)發(fā)生泄漏亮蒋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一妆毕、第九天 我趴在偏房一處隱蔽的房頂上張望慎玖。 院中可真熱鬧,春花似錦笛粘、人聲如沸趁怔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽润努。三九已至关斜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間任连,已是汗流浹背蚤吹。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工例诀, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留随抠,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓繁涂,卻偏偏與公主長得像拱她,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扔罪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 完成上一篇的配置秉沼,現(xiàn)在我們可以在 SAP 系統(tǒng)中創(chuàng)建基于 SAP Netweaver Gateway 的 ODat...
    Stone0823閱讀 6,282評論 3 8
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)矿酵,斷路器唬复,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,071評論 25 707
  • 準(zhǔn)備分三個部分介紹如何連接到后端 SAP 系統(tǒng),先說明 SAP 系統(tǒng)提供 OData 服務(wù)所需的配置全肮。 SAP 通...
    Stone0823閱讀 3,161評論 1 4
  • 雨過申城洗嬌容敞咧,閑游風(fēng)雨黃昏后 滿城頑云撥不開,遠(yuǎn)山映隱游霧中 蠶鳴蛙聲吟啼意辜腺,綠樹青絲繞尋處 柔水碧波照黃燈 休建,...
    曾居然閱讀 286評論 0 2