从SAPUI5消耗OData V4

时间:2019-07-07 03:59:14

标签: sapui5 odata-v4

我正在尝试将OData V4与SAPUI5一​​起使用。尽管看起来很简单,但我面临着两个问题。

我正在使用Demokit中的sap.ui.layout.sample.SimpleFormToolbar示例。实现了OData V4服务,以简单形式显示数据。

我在此应用中所做的更改:
1. manifest.json和
2.用于表单控件的上下文绑定的Page.view.xml
3.删除了控制器和index.html

中对模拟数据的代码引用

但是,我无法获得以下错误的数据:

2019-07-07 08:58:23.736110 Failed to update path /Suppliers(12345)/Country - **Error: Must not change a property before it has been read**

**Uncaught Error: Must not change a property before it has been read**

另一个错误是与批处理模式有关。我尚未在Odata impl中实现任何批处理。

2019-07-07 08:58:24.279114 **$batch failed** - Error: Network error
2019-07-07 08:58:24.281175 Failed to read path /Suppliers(12345) - Error: **HTTP request was not processed because $batch failed**

我使用的代码是:

// manifest.json

{
    "_version": "1.12.0",
    "sap.app": {
        "id": "sap.ui.layout.sample.SimpleFormToolbar",
        "applicationVersion": {
            "version": "1.0.0"
        },
        "dataSources": {
          "supplierOData": {
            "uri": "https://supplierappp1014576trial.hanatrial.ondemand.com/SupplierApp/SupplierService.svc/",
            "type": "OData",
            "settings": {
              "odataVersion": "4.0"
            }
          }
        }
    },
    "sap.ui5": {
        "rootView": {
            "viewName": "sap.ui.layout.sample.SimpleFormToolbar.Page",
            "type": "XML",
            "async": true
        },
        "dependencies": {
            "libs": {
                "sap.ui.layout": {}
            }
        },
        "models": {
            "": {
                "dataSource": "supplierOData",
                "settings" : {
                    "synchronizationMode" : "None"
                }
            }
        },
        "config": {
            "sample": {
                "files": [
                    "Page.view.xml",
                    "Page.controller.js",
                    "manifest.json"
                ]
            }
        }
    }
}

// Page.view.xml

<mvc:View
    controllerName="sap.ui.layout.sample.SimpleFormToolbar.Page"
    xmlns:l="sap.ui.layout"
    xmlns:f="sap.ui.layout.form"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:core="sap.ui.core"
    xmlns="sap.m">
    <VBox class="sapUiSmallMargin">
        <f:SimpleForm id="SimpleFormToolbar"
            binding="{/Suppliers(12345)}"
            editable="true"
            layout="ResponsiveGridLayout"
            labelSpanXL="4"
            labelSpanL="3"
            labelSpanM="4"
            labelSpanS="12"
            adjustLabelSpan="false"
            emptySpanXL="0"
            emptySpanL="4"
            emptySpanM="0"
            emptySpanS="0"
            columnsXL="2"
            columnsL="1"
            columnsM="1"
            singleContainerFullSize="false"
            ariaLabelledBy="Title1" >
            <f:toolbar>
                <Toolbar id="TB1">
                    <Title id="Title1" text="Address" level="H4" titleStyle="H4"/>
                    <ToolbarSpacer />
                    <Button icon="sap-icon://settings"/>
                    <Button icon="sap-icon://drop-down-list" />
                </Toolbar>
            </f:toolbar>
            <f:content>
                <Toolbar ariaLabelledBy="Title2">
                    <Title id="Title2" text="Office" level="H5" titleStyle="H5"/>
                    <ToolbarSpacer />
                    <Button icon="sap-icon://settings"/>
                </Toolbar>
                <Label text="Name" />
                <Input value="{SupplierName}" />
                <Label text="Street/No." />
                <Input value="{Street}">
                </Input>
                <Input value="{HouseNumber}">
                    <layoutData>
                        <l:GridData span="XL2 L1 M3 S4" />
                    </layoutData>
                </Input>
                <Label text="ZIP Code/City" />
                <Input value="{ZIPCode}">
                    <layoutData>
                        <l:GridData span="XL2 L1 M3 S4" />
                    </layoutData>
                </Input>
                <Input value="{City}" />
                <Label text="Country" />
                <Select id="country" selectedKey="{Country}">
                    <items>
                        <core:Item text="England" key="England"/>
                        <core:Item text="Germany" key="Germany"/>
                        <core:Item text="USA" key="USA"/>
                    </items>
                </Select>
                <Toolbar ariaLabelledBy="Title3">
                    <Title id="Title3" text="Online" level="H5" titleStyle="H5"/>
                    <ToolbarSpacer />
                    <Button icon="sap-icon://settings"/>
                </Toolbar>
                <Label text="Web" />
                <Input value="{Url}" type="Url" />
                <Label text="Twitter" />
                <Input value="{Twitter}" />
            </f:content>
        </f:SimpleForm>
    </VBox>
</mvc:View>

// Page.controller.js

sap.ui.define([
        'jquery.sap.global',
        'sap/ui/core/mvc/Controller',
        'sap/ui/model/json/JSONModel',
        'sap/ui/model/odata/v4/ODataModel'
    ], function(jQuery, Controller, JSONModel, ODataModel) {
    "use strict";

    var PageController = Controller.extend("sap.ui.layout.sample.SimpleFormToolbar.Page", {

        onInit: function (oEvent) {
            console.log("hello");

            jQuery.get({
                url: "/SupplierService/SupplierService.svc/Suppliers(12345)",
                success: function(data) {
                    console.log( "Recieved data: " + data);
                },
                error: function(error) {
                    // your error logic
                    console.log("Error while requesting odata: " + error);
                }
            });


        }

    });


    return PageController;

});

// index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="expires" content="0">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fullscreen – with toolbar</title>

    <script id="sap-ui-bootstrap"
        src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
        data-sap-ui-theme="sap_belize"
        data-sap-ui-resourceroots='{
            "sap.ui.layout.sample.SimpleFormToolbar": "./",
            "sap.ui.demo.mock": "mockdata"
        }'
        data-sap-ui-compatVersion="edge"
        data-sap-ui-async="true"
        data-sap-ui-preload=""
        data-sap-ui-frameOptions="trusted"
        data-sap-ui-oninit="module:sap/ui/core/ComponentSupport">
    </script>
</head>

<body class="sapUiBody" id="content">
    <div data-sap-ui-component
        data-name="sap.ui.layout.sample.SimpleFormToolbar"
        data-height="100%"
        data-id="container"
        data-settings='{"id" : "sap.ui.layout.sample.SimpleFormToolbar"}'
        style="height: 100%">
    </div>
</body>
</html>

我添加了jquery调用只是为了查看odata是否正常工作。

用于CORS问题的命令:“ C:\ Program Files(x86)\ Google \ Chrome \ Application \ chrome.exe” --disable-web-security --disable-gpu --user-data-dir =〜 / chromeTemp

我实际上是指向同一项目中的odata服务。相同的部署在Sap Cloud上:https://supplierappp1014576trial.hanatrial.ondemand.com/SupplierApp/SupplierService.svc/

感谢您的时间。

  • 编辑:

在下面将解决方案添加为答案。

1 个答案:

答案 0 :(得分:1)

  • 错误:

    “在读取属性之前不得更改属性”被理解为 CORS问题 。 通过配置web.xml可以在服务器端接受跨源请求。请注意,应针对生产用途进行重新评估。

<filter>
          <filter-name>CorsFilter</filter-name>
          <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>CorsFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
  • 错误:

    通过将 groupId更改为$ direct ,可以解决“ $批处理失败-错误:网络错误”的问题。这意味着我们将向odata服务发送单个网络呼叫。


"models": {
            "": {
                "dataSource": "supplierOData",
                "settings" : {
                    "synchronizationMode" : "None",
                    "groupId": "$direct"
                }
            }
        },

这消除了那些错误,我看到数据已呈现到表单字段中。

感谢您的关注。