美文网首页
SAPUI5 (26) - 基于 ODataModel 的增删改

SAPUI5 (26) - 基于 ODataModel 的增删改

作者: Stone0823 | 来源:发表于2017-03-15 22:19 被阅读459次

    http://services.odata.org 提供了允许进行 CRUD 的 OData 数据服务 ( OData data service ),版本为 v2,可以通过 http://services.odata.org/V2/(S(user-session-token))/OData/OData.svc/ 访问。其中 user-session-token 需要替换成进入时网站分配的的 token , CRUD 也仅对该 Session 有效。

    本篇介绍基于 OData v2,对 Northwind online data service 进行 CRUD 操作。介绍的重点包括:

    • http 请求;

    • 使用 Postman 发送 http 请求;

    • 使用 ODataModel(v2) 提交 CRUD 方法和查看返回结果。

    读取数据

    OData Service 读取数据(Read)

    读取 OData service 提供的数据,通过 http 的 GET 方法。如果请求成功,返回的状态码为 200,如果请求的资源不存在,返回的状态码为 404.。请求的数据可以是一个实体,也可以是一个集合 ( Set )。

    我们先借助 Postman 这个 Chrome 插件来查看 Northwind 数据服务。我们来查看第一个供应商的信息:

    操作界面:

    返回的结果:如上图所示。

    ODataModel ( v2 ) 读取 Odata 数据

    首先指定 Service URL,因为 Same-origin 原因,使用代理( 请替换成自己的 user-session-token ):

    var sServiceUrl = "https://cors-anywhere.herokuapp.com/" 
                    + "http://services.odata.org/V2/(S(tigt4zfne0egj3u25bhqq32a))/OData/OData.svc/";
    

    读取数据的操作放在 readSupplier() 函数中:

    // 读取供应商
    function readSupplier(){
        var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);     
        
        function fnSuccess(oData, oResponse){
            console.log("Response", oResponse);
            console.log("Data", oData);
        }
        
        function fnError(oError){
            console.log("Error", oError);
        }
        
        // 读取存在的 supplier
        oModel.read("/Suppliers(0)", {
            success: fnSuccess,
            error: fnError
        });
        
        // 故意读取一个不存在的 supplier
        oModel.read("/Suppliers(12222)", {
                success: fnSuccess,
                error: fnError
        });
    }
    

    在 Chrome 浏览器中运行,按下 F12, 在开发者工具的 Console 选项卡中查看结果,因为第一次第一次读取的供应商 ID 存在,所以返回 200 状态码,成功。这是读取第一个供应商返回的对象:

    因为第二个供应商不存在,所以返回错误状态码 404 - Not found。下图是读取第二个供应商返回的错误的界面:

    ODataModel 读取数据的要点

    • ODataModelread() 方法触发一个 GET 请求,如果请求成功,执行 success 回调函数,该函数的 oData 参数包含 response 返回的数据,失败则执行 error 回调函数。

    • 请求后返回的数据缓存在 OData model 中,可以调用 getData() 方法(这个方法已经废弃),这个方法返回整个实体 ( Entity ) ; 调用 getProperty() 方法,返回实体中的某一属性。这两个方法都不触发 http 请求,所以获得的是已经请求过并保存在缓存中的数据。示例如下:

    // 读取 OData model 缓存的数据
    function getData(){        
        var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);     
        
        oModel.read("/Suppliers", {        
            success: function(oData, oResponse){
                // 两种方法读取 supplier name
                var oSupplier = oModel.getData("/Suppliers(1)");
                console.log(oSupplier.Name);  // 方法1
                console.log(oModel.getProperty("/Suppliers(1)/Name"));  // 方法2
            },
            
            error: function(oError){
                console.log("Error", oError);
            }
        });         
    }
    
    • oDataModel.read() 方法从 OData data service 获取所有供应商放在 oModel 的缓存中,然后通过 getData("/Suppliers(0)") 获取第一个供应商。因为 oSupplier 是一个对象,所以可以通过 oSupplier.Name 获取供应商名称,也可直接通过 oModel.getProperty("/Suppliers(0)/Name) 获取供应商名称。

    • OData data service 的元数据 ( metadata ) 在 read() 方法调用后后被加载到客户端缓存。如果多个 OData model 使用同一个 url,则它们共享一个元数据,只有第一个 model 的请求会触发获取 $metadata 请求。元数据的加载是异步的,并且也不能被设置为同步的。元数据是 XML 格式的,但 OData modelgetServiceMetadata() 获取到的 model 元数据为元数据所对应的 json 格式。

    新建数据

    OData Service 可以使用 HTTP 协议的 POST 方法提交创建数据的请求,如果成功,返回的状态码为 201。

    在 Chrome 插件 Postman 中提交 POST 请求,可以先用 GET 方法读取一条数据,然后将返回的数据拷贝出来进行修改的方式,简化操作过程。比如,我们想要创建一个新供应商,编号为 #101:

    在 Postman 中,选择 POST 方法,URL 中输入:http://services.odata.org/V2/(S(tigt4zfne0egj3u25bhqq32a))/OData/OData.svc/Suppliers。POST 请求的 URL 是一个集合。然后切换到 headers ,指定 Content-typeapplication/json

    最后再切换到 Body,使用 Raw 格式,编写要提交的数据:

    使用 ODataModel 创建供应商

    // 创建供应商
    function createSupplier(){
        var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);
        oModel.setUseBatch(false);
        oModel.setHeaders({
            "Content-type":"application/json"
        });
        
        function fnSuccess(oData, oResponse){
            console.log("Response", oResponse);
        }
        
        function fnError(oError){
            console.log("Error", oError);
        }
        
        var oNewSupplier = {
                "ID": 101,
                "Name": "Stone测试供应商#101",
                "Address": {
                    "Street": "三角湖路",
                    "City": "武汉",
                    "State": "HB",
                    "ZipCode": "430060",
                    "Country": "中国"
                }
            };
        
        oModel.create("/Suppliers", oNewSupplier, {
            success: fnSuccess,
            error: fnError
        });             
    }
    

    修改数据

    修改数据使用 PUT 方法,在 Postman 中操作时,选择 PUT 方法,URL 为:http://services.odata.org/V2/(S(tigt4zfne0egj3u25bhqq32a))/OData/OData.svc/Suppliers(101),Headers 页面添加 Content-type 和 If-match:

    然后到 Body 页面,选择 Raw,编辑需要修改的数据:

    如果请求成功,返回状态码为 204 - No content。

    使用 ODataModel 修改数据的代码:

    // 修改供应商
    function editSupplier(){
        var oModel = new sap.ui.model.odata.v2.ODataModel({
            serviceUrl: sServiceUrl,
            headers: {
                "If-match": "*"
            }});
        
        var oChanges = {                        
                "Name": "Stone测试供应商#101",
                "Address": {
                    "Street": "博学路",
                    "City": "武汉",
                    "State": "HB",
                    "ZipCode": "430060",
                    "Country": "China"
                }
            };
        oModel.update("/Suppliers(101)", oChanges, {
            success: function(oData, oResponse){
                console.log("Response", oResponse);
            },
            error: function(oError){
                console.log("Error", oError);
            }
        });
    }
    

    删除数据

    删除 OData 的数据使用 DELETE 方法,在 Postman 中操作时,选择 DELETE 方法,URL 为:http://services.odata.org/V2/(S(tigt4zfne0egj3u25bhqq32a))/OData/OData.svc/Suppliers(101)。Headers 需要指定 If-match:

    因为删除数据不需要提交额外的数据,所以 Body 部分为空。如果请求成功,返回的状态码为 204 - No content。

    使用 ODataModel 删除数据的代码如下:

    // 删除供应商
    function deleteSupplier(){  
        var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);     
        
        // set headers
        oModel.setHeaders({
            "If-match": "*"
        });
        
        oModel.remove("/Suppliers(101)", {
            success: function (oData, oResponse){
                console.log(oResponse);
            }, 
            error: function (oError){
                console.log(oError);
            }
        });             
    }       
    

    最后给出测试的完整代码:

    <!DOCTYPE HTML>
    <html>
        <head>
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
    
            <script src="../../resources/sap-ui-core.js"
                    id="sap-ui-bootstrap"
                    data-sap-ui-libs="sap.m"
                    data-sap-ui-theme="sap_bluecrystal">
            </script>
            <!-- only load the mobile lib "sap.m" and the "sap_bluecrystal" theme -->
    
            <script>
                var sServiceUrl = "https://cors-anywhere.herokuapp.com/" 
                                + "http://services.odata.org/V2/(S(tigt4zfne0egj3u25bhqq32a))/OData/OData.svc/";
                            
                // 读取供应商
                function readSupplier(){
                    var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);     
                    
                    function fnSuccess(oData, oResponse){
                        console.log("Response", oResponse);
                        console.log("Data", oData);
                    }
                    
                    function fnError(oError){
                        console.log("Error", oError);
                    }
                    
                    // 读取存在的 supplier
                    oModel.read("/Suppliers(0)", {
                        success: fnSuccess,
                        error: fnError
                    });
                    
                    // 读取不存在的 supplier
                    oModel.read("/Suppliers(12222)", {
                            success: fnSuccess,
                            error: fnError
                    });
                }
                
                // 读取 OData model 缓存的数据
                function getData(){        
                    var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);     
                    
                    oModel.read("/Suppliers", {
                        
                        success: function(oData, oResponse){
                            // 两种方法读取 supplier name
                            var oSupplier = oModel.getData("/Suppliers(1)");
                            console.log(oSupplier.Name);
                            console.log(oModel.getProperty("/Suppliers(1)/Name"));
                        },
                        
                        error: function(oError){
                            console.log("Error", oError);
                        }
                    });         
                }
    
                // 创建供应商
                function createSupplier(){
                    var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);
                    oModel.setUseBatch(false);
                    oModel.setHeaders({
                        "Content-type":"application/json"
                    });
                    
                    function fnSuccess(oData, oResponse){
                        console.log("Response", oResponse);
                    }
                    
                    function fnError(oError){
                        console.log("Error", oError);
                    }
                    
                    var oNewSupplier = {
                            "ID": 101,
                            "Name": "Stone测试供应商#101",
                            "Address": {
                              "Street": "三角湖路",
                              "City": "武汉",
                              "State": "HB",
                              "ZipCode": "430060",
                              "Country": "中国"
                            }
                        };
                    
                    oModel.create("/Suppliers", oNewSupplier, {
                        success: fnSuccess,
                        error: fnError
                    });             
                }
                
                // 修改供应商
                function editSupplier(){
                    var oModel = new sap.ui.model.odata.v2.ODataModel({
                        serviceUrl: sServiceUrl,
                        headers: {
                            "If-match": "*"
                        }});
                    
                    var oChanges = {                        
                            "Name": "Stone测试供应商-#101",
                            "Address": {
                              "Street": "博学路",
                              "City": "武汉",
                              "State": "HB",
                              "ZipCode": "430060",
                              "Country": "China"
                            }
                        };
                    oModel.update("/Suppliers(101)", oChanges, {
                        success: function(oData, oResponse){
                            console.log("Response", oResponse);
                        },
                        error: function(oError){
                            console.log("Error", oError);
                        }
                    });
                }
                
                // 删除供应商
                function deleteSupplier(){  
                    var oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);     
                    
                    // set headers
                    oModel.setHeaders({
                        "If-match": "*"
                    });
                    
                    oModel.remove("/Suppliers(101)", {
                        success: function (oData, oResponse){
                            console.log(oResponse);
                        }, 
                        error: function (oError){
                            console.log(oError);
                        }
                    });             
                }           
    
            
                sap.ui.getCore().attachInit(function(){                     
                    var oReadButton = new sap.m.Button({
                        text: "Read",
                        press: readSupplier
                    });
                    
                    var oGetDataButton = new sap.m.Button({
                        text: "Get data",
                        press: getData
                    });
                    
                    var oCreateButton = new sap.m.Button({
                        text: "Create",
                        press: createSupplier
                    });
                    
                    var oEditButton = new sap.m.Button({
                        text: "Edit",
                        press: editSupplier
                    });
                    
                    var oDeleteButton = new sap.m.Button({
                        text: "Delete",
                        press: deleteSupplier
                    });
                    
                    var oPage = new sap.m.Page({
                        title: "基于oData Model的增删改查",
                        content: [oReadButton, oGetDataButton, oCreateButton, oEditButton, oDeleteButton]
                    });
                    
                    var oApp = new sap.m.App({
                        initialPage: oPage
                    });
                    
                    oApp.addPage(oPage);
                    oApp.placeAt("content");                
                });         
                
            </script>
    
        </head>
        <body class="sapUiBody" role="application">
            <div id="content"></div>
        </body>
    </html>
    

    源代码

    26_zui5_odata_crud_northwind

    相关文章

      网友评论

          本文标题:SAPUI5 (26) - 基于 ODataModel 的增删改

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