Step 26: (Optional) Remote OData Service
使用远程的OData。
修改manifest.json
{ "_version": "1.12.0", "sap.app": { ... "ach": "CA-UI5-DOC", "dataSources": { "invoiceRemote": { "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/", "type": "OData", "settings": { "odataVersion": "2.0" } } } }, "sap.ui": { ... }, "sap.ui5": { ... "models": { "i18n": { "type": "sap.ui.model.resource.ResourceModel", "settings": { "bundleName": "sap.ui.demo.walkthrough.i18n.i18n" } }, "invoice": { "dataSource": "invoiceRemote" } } } }
在sap.app中添加数据源的配置,指定服务的type为odata,uri为该odata的地址,版本为2.0版本。
将model invoice的数据源,指定为invoiceRemote,会在组件初始化的时候,实例化模型。此配置允许组件在应用程序启动时,检索此模型的技术信息。
如果你希望在组件上有一个默认模型,那么可以在models中将模型命名为空字符串,
可以在component上使用this.getModel,来获取被自动实例化的model。
在基于component上的controller中,可以使用this.getView().getModel(),来获取被自动实例化的model。
如果要检索指定的model,那么需要将model的名字传递给getModel,比如这里用this.getModel("invoice") 。
运行之后会出现cross-origin的错误,可以在下面link中查看解决方法。
Step 27: Mock Server Configuration
为了调试或者测试,我们需要使用Mock Server 来模拟odata。
我们将测试文件与生产文件分开,创建一个新的test文件夹,并创建一个文件mockServer.html,用来以测试的模式启动我们的程序。
在localService文件夹中,创建一个用来描述odata的metadata.xml,mockserver.js使用本地数据模拟真实的服务,mockdata里面包括本地测试数据。
新建webapp/test/mockServer.html (New)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SAPUI5 Walkthrough</title>
<script
id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m"
data-sap-ui-resourceroots='{
"sap.ui.demo.walkthrough": "./"
}'
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
data-sap-ui-compatVersion="edge"
data-sap-ui-async="true">
</script>
</head>
<body class="sapUiBody" id="content">
<div data-sap-ui-component data-name="sap.ui.demo.walkthrough" data-id="container" data-settings='{"id" : "walkthrough"}'></div>
</body>
</html>
拷贝index.html到test文件夹中,改名为test/mockServer.html。
这样我们对于应用程序有两个入口,一个为index.html,一个为mockServer.html。
修改刚刚创建的webapp/test/mockServer.html (New)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SAPUI5 Walkthrough - Test Page</title> <script id="sap-ui-bootstrap" src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" data-sap-ui-theme="sap_belize" data-sap-ui-resourceroots='{ "sap.ui.demo.walkthrough": "../" }' data-sap-ui-oninit="module:sap/ui/demo/walkthrough/test/initMockServer" data-sap-ui-compatVersion="edge" data-sap-ui-async="true"> </script> </head> <body class="sapUiBody" id="content"> <div data-sap-ui-component data-name="sap.ui.demo.walkthrough" data-id="container" data-settings='{"id" : "walkthrough"}'></div> </body> </html>
data-sap-ui-resourceroots指向当前程序的上一级目录,因为当前文件位于test文件夹中,同时调用脚本initMockServer,用来启动程序。
新建webapp/test/initMockServer.js (New)
sap.ui.define([
"../localService/mockserver"
], function (mockserver) {
"use strict";
// initialize the mock server
mockserver.init();
// initialize the embedded component on the HTML page
sap.ui.require(["sap/ui/core/ComponentSupport"]);
});
mockserver的init方法被调用,用来启动mockserver。
创建webapp/localService/mockdata/Invoices.json (New)
[
{
"ProductName": "Pineapple",
"Quantity": 21,
"ExtendedPrice": 87.2000,
"ShipperName": "Fun Inc.",
"ShippedDate": "2015-04-01T00:00:00",
"Status": "A"
},
{
"ProductName": "Milk",
"Quantity": 4,
"ExtendedPrice": 9.99999,
"ShipperName": "ACME",
"ShippedDate": "2015-02-18T00:00:00",
"Status": "B"
},
{
"ProductName": "Canned Beans",
"Quantity": 3,
"ExtendedPrice": 6.85000,
"ShipperName": "ACME",
"ShippedDate": "2015-03-02T00:00:00",
"Status": "B"
},
{
"ProductName": "Salad",
"Quantity": 2,
"ExtendedPrice": 8.8000,
"ShipperName": "ACME",
"ShippedDate": "2015-04-12T00:00:00",
"Status": "C"
},
{
"ProductName": "Bread",
"Quantity": 1,
"ExtendedPrice": 2.71212,
"ShipperName": "Fun Inc.",
"ShippedDate": "2015-01-27T00:00:00",
"Status": "A"
}
]
创建webapp/localService/metadata.xml (New)
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema Namespace="NorthwindModel" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityType Name="Invoice">
<Key>
<PropertyRef Name="ProductName"/>
<PropertyRef Name="Quantity"/>
<PropertyRef Name="ShipperName"/>
</Key>
<Property Name="ShipperName" Type="Edm.String" Nullable="false" MaxLength="40" FixedLength="false"
Unicode="true"/>
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" FixedLength="false"
Unicode="true"/>
<Property Name="Quantity" Type="Edm.Int16" Nullable="false"/>
<Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4"/>
</EntityType>
</Schema>
<Schema Namespace="ODataWebV2.Northwind.Model" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityContainer Name="NorthwindEntities" m:IsDefaultEntityContainer="true" p6:LazyLoadingEnabled="true"
xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
<EntitySet Name="Invoices" EntityType="NorthwindModel.Invoice"/>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
metadata.xml用来对odata进行描述。一般不需要手动编写。
新建webapp/localService/mockserver.js (New)
sap.ui.define([
"sap/ui/core/util/MockServer",
"sap/base/util/UriParameters"
], function (MockServer, UriParameters) {
"use strict";
return {
init: function () {
// create
var oMockServer = new MockServer({
rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/"
});
var oUriParameters = new UriParameters(window.location.href);
// configure mock server with a delay
MockServer.config({
autoRespond: true,
autoRespondAfter: oUriParameters.get("serverDelay") || 500
});
// simulate
var sPath = "../localService";
oMockServer.simulate(sPath + "/metadata.xml", sPath + "/mockdata");
// start
oMockServer.start();
}
};
});
使用MockServer models作为一个依赖项进行加载,创建一个helps对象,定义一个init方法。此方法在上述mockServer.html文件中的组件初始化之前调用。init方法还使用与实际服务相同的URL创建MockServer实例。
rootUri的参数与定义在manifest.json文件中的参数一致,可以是绝对url,也可以是一个相对的url,比如定义在web ide中的destination。
这个URL现在将由我们的测试服务器提供,而不是真正的服务。接下来,我们设置两个全局配置设置,它们告诉服务器自动响应,并引入1秒的延迟来模拟典型的服务器响应时间。否则,我们必须手动调用MockServer上的response方法来模拟调用。
为了模拟服务,我们可以简单地调用MockServer实例上的simulate方法,并提供metadata.xml的路径。这将从我们的本地文件系统读取测试数据,并模拟真实的服务。
最后,我们调用oMockServer上的start。从现在开始,每个对rootUri的请求都将由MockServer处理。如果您在浏览器中从index.html文件切换到mockServer.html文件,您现在可以看到测试数据从本地源显示,但是有一个短暂的延迟。可以使用URI参数serverDelay指定延迟,默认值为1秒。