Consuming OData V4 from SAPUI5
我正在尝试将 OData V4 与 SAPUI5 一起使用。虽然看起来很简单,但我面临着几个问题。
我正在使用来自 Demokit 的 sap.ui.layout.sample.SimpleFormToolbar 示例。实现了一个 OData V4 服务以简单的形式显示数据。
我在这个应用程序中所做的更改:
1. manifest.json 和
2. 表单控件的Context Binding的Page.view.xml
3.删除了controller和index.html
中mockdata的代码引用
但是,由于以下错误,我无法获取数据:
1 2 3 | 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 中实现任何批处理。
1 2 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | { "_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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | <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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <!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"> Fullscreen –with toolbar <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"> </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%"> </body> </html> |
我添加了 jquery 调用只是为了查看 odata 是否正常工作。
用于 CORS 问题的命令:"C:\\\\\\\\Program Files (x86)\\\\\\\\Google\\\\\\\\Chrome\\\\\\\\Application\\\\\\\\chrome.exe" --disable-网络安全 --disable-gpu --user-data-dir=~/chromeTemp
我实际上指向的是同一个项目中的 odata 服务。同样部署在 Sap Cloud 上:https://supplierappp1014576trial.hanatrial.ondemand.com/SupplierApp/SupplierService.svc/
感谢您的宝贵时间。
- 编辑:
在下面添加了解决方案作为答案。
-
错误:
"在读取之前不得更改属性" 被理解为 CORS 问题。
在服务器端接受跨域请求可以通过配置 web.xml 来完成。请注意,这应该重新评估以供生产使用。
1
2
3
4
5
6
7
8 <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>
-
错误:
"$batch failed - Error: Network error" 可以通过将 groupId 更改为 $direct 来解决。这意味着我们正在向 odata 服务发送单独的网络调用。
1 2 3 4 5 6 7 8 9 | "models": { "": { "dataSource":"supplierOData", "settings" : { "synchronizationMode" :"None", "groupId":"$direct" } } }, |
这消除了这些错误,我看到数据被呈现到表单字段中。
感谢您的关注。