说明
到目前为止,我们把所有的应用内容放在一个页面上。当我们添加越来越多的功能时,我们希望将内容分开,并将其放在单独的页面上。
在这一步中,我们将使用SAPUI5导航特性来加载和显示一个单独的详细页面,稍后我们可以使用该页面来显示发票的详细信息。在前面的步骤中,我们直接在应用程序视图中定义了页面,以便在应用程序加载时显示它。现在,我们将使用SAPUI5 router类来自动加载页面并更新URL。我们为应用指定一个路由配置,并为应用的每个页面创建一个单独的视图,然后通过触发导航事件连接视图。
预览
添加第二页以显示发票
代码
您可以在演练-步骤31查看和下载所有文件。
webapp/manifest.json
{
"_version": "1.12.0",
…
"sap.ui5": {
…
"models": {
…
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"viewPath": "sap.ui.demo.walkthrough.view",
"controlId": "app",
"controlAggregation": "pages",
"async": true
},
"routes": [
{
"pattern": "",
"name": "overview",
"target": "overview"
},
{
"pattern": "detail",
"name": "detail",
"target": "detail"
}
],
"targets": {
"overview": {
"viewId": "overview",
"viewName": "Overview"
},
"detail": {
"viewId": "detail",
"viewName": "Detail"
}
}
}
}
}
我们在描述符的sap.ui5部分添加了一个新的“routing”部分。有三个子部分定义了应用的路由和导航结构:
- config
本节包含全局路由器配置和应用与所有routes和targets的缺省值。我们定义了我们想要使用的路由器类以及我们的视图在应用程序中的位置。为了自动加载和显示视图,我们还指定使用哪个控件来显示页面,以及在显示新页面时应该填充什么聚合。- routes
每条路由都定义了一个name、一个pattern和一个或多个targets,以便在到达路由时导航到。pattern基本上是与路由匹配的URL部分,我们为应用程序定义了两个路由。第一个是默认路由,它将显示包含前面步骤内容的概览页面,第二个是带有URL pattern detail的详细路由,它将显示一个新页面。- targets
targets定义了显示的视图,它与一个或多个路由相关联,它也可以在应用程序中手动显示。每当一个目标被显示时,相应的视图就会被加载并显示在应用程序中。在我们的应用程序中,我们简单地定义了两个带有对应目标视图名称的targets。
webapp/Component.js
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel",
"./controller/HelloDialog"
], function (UIComponent, JSONModel, HelloDialog) {
"use strict";
return UIComponent.extend("sap.ui.demo.walkthrough.Component", {
metadata: {
manifest: "json"
},
init: function () {
// call the init function of the parent
UIComponent.prototype.init.apply(this, arguments);
// set data model
var oData = {
recipient: {
name: "World"
}
};
var oModel = new JSONModel(oData);
this.setModel(oModel);
// set dialog
this._helloDialog = new HelloDialog(this.getRootControl());
// create the views based on the url/hash
this.getRouter().initialize();
},
exit : function () {
this._helloDialog.destroy();
delete this._helloDialog;
},
openHelloDialog : function () {
this._helloDialog.open();
}
});
});
在组件初始化方法中,我们现在添加一个调用来初始化路由器。我们不需要手动实例化路由器,它会根据AppDescriptor配置自动实例化并分配给组件。
初始化路由器将评估当前URL并自动加载相应的视图。这是在AppDescriptor中配置的routes和targets的帮助下完成的。如果路由被命中,则加载并显示相应目标的视图。
webapp/view/Overview.view.xml (New)
<mvc:View
controllerName="sap.ui.demo.walkthrough.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page title="{i18n>homePageTitle}">
<headerContent>
<Button
icon="sap-icon://hello-world"
press=".onOpenDialog"/>
</headerContent>
<content>
<mvc:XMLView viewName="sap.ui.demo.walkthrough.view.HelloPanel"/>
<mvc:XMLView viewName="sap.ui.demo.walkthrough.view.InvoiceList"/>
</content>
</Page>
</mvc:View>
我们将前面步骤的内容从App视图移动到一个新的Overview视图。为简单起见,我们不更改控制器,因为它只包含打开对话框的助手方法,这意味着我们为两个不同的视图(对于新的overview和App视图)重用控制器sap.ui.demo.walkthrough.controller.App。然而,该控制器的两个实例是在运行时实例化的。通常,每个引用控制器的视图都会实例化一个控制器的实例。
webapp/view/App.view.xml
<mvc:View
controllerName="sap.ui.demo.walkthrough.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
displayBlock="true">
<Shell>
<App class="myAppDemoWT" id="app"/>
</Shell>
</mvc:View>
我们的App视图现在只包含空的App标签。路由器会自动将当前URL对应的视图添加到应用程序控件中。路由器用与AppDescriptor中的属性controlId: “app”相对应的ID来标识应用控件。
webapp/view/Detail.view.xml (New)
<mvc:View
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page
title="{i18n>detailPageTitle}">
<ObjectHeader
title="Invoice"/>
</Page>
</mvc:View>
现在我们添加第二个视图detail。它只包含一个页面和ObjectHeader控件,该控件目前显示静态文本Invoice。
webapp/i18n/i18n.properties
…
# Invoice List
invoiceListTitle=Invoices
invoiceStatusA=New
invoiceStatusB=In Progress
invoiceStatusC=Done
# Detail Page
detailPageTitle=Walkthrough - Details
我们将一个新字符串添加到资源包中,用于详细页面标题。
webapp/view/InvoiceList.view.xml
<mvc:View
controllerName="sap.ui.demo.walkthrough.controller.InvoiceList"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<List …>
…
<items>
<ObjectListItem
title="{invoice>Quantity} x {invoice>ProductName}"
number="{
parts: [{path: 'invoice>ExtendedPrice'}, {path: 'view>/currency'}],
type: 'sap.ui.model.type.Currency',
formatOptions: {
showMeasure: false
}
}"
numberUnit="{view>/currency}"
numberState="{= ${invoice>ExtendedPrice} > 50 ? 'Error' : 'Success' }"
type="Navigation"
press="onPress">
<firstStatus>
<ObjectStatus text="{
path: 'invoice>Status',
formatter: '.formatter.statusText'
}"/>
</firstStatus>
</ObjectListItem>
</items>
</List>
</mvc:View>
在发票列表视图中,我们向列表项添加一个press事件,并将item类型设置为Navigation,以便可以实际单击该项。
webapp/controller/InvoiceList.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"../model/formatter",
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator"
], function (Controller, JSONModel, formatter, Filter, FilterOperator) {
"use strict";
return Controller.extend("sap.ui.demo.walkthrough.controller.InvoiceList", {
…
onPress: function (oEvent) {
var oRouter = this.getOwnerComponent().getRouter();
oRouter.navTo("detail");
}
});
});
我们将事件处理程序函数添加到发票列表的控制器中。现在是时候通过单击发票列表中的项目导航到详细页面了。我们通过调用helper方法getOwnerComponent().getRouter()来访问应用程序的路由器实例。在路由器上,我们调用navTo方法导航到我们在路由配置中指定的detail路由。
现在,当您单击发票列表中的一个项目时,应该可以看到详细页面。
约定
- 在描述符中定义路由配置
相关信息
章节
- 第1步:你好世界
- 第2步:引导
- 第3步:控件
- 第4步:XML视图
- 第5步:控制器
- 第6步:模块
- 第7步:JSON模型
- 第8步:可翻译的文本
- 第9步:组件配置
- 第10步:应用程序描述符
- 第11步:页面和面板
- 第12步:Shell控件作为容器
- 第13步:外边距和内边距
- 第14步:自定义CSS和主题颜色
- 第15步:嵌套视图
- 第16步:对话框和片段
- 第17步:片段回调
- 第18步:图标
- 第19步:重用对话框
- 第20步:聚合绑定
- 第21步:数据类型
- 第22步:表达式绑定
- 第23步:自定义格式器
- 第24步:过滤
- 第25步:排序和分组
- 第26步:远程OData服务
- 第27步:模拟服务器配置
- 第28步:使用QUnit进行单元测试
- 第29步:与OPA的集成测试
- 第30步:调试工具
- 第31步:路由和导航
- 第32步:路由与参数
- 第33步:路由回溯和历史
- 第34步:自定义控件
- 第35步:响应性
- 第36步:设备适应
- 第37步:内容密度
- 第38步:可访问性