上一章讲了路由和导航的基础知识。
SAP学习笔记 - 开发27 - 前端Fiori开发 Routing and Navigation(路由和导航)-CSDN博客
本章继续学习SAP Fiori开发的知识。
目录
1,Routing with Parameters(带参数的路由)
2,Routing Back and History(路由返回和履历)
下面是详细内容。
1,Routing with Parameters(带参数的路由)
其实就是页面间传参的事情。
1),manifest.json
{
"_version": "1.65.0",
"sap.app": {
"id": "ui5.walkthrough",
"i18n": "i18n/i18n.properties",
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"type": "application",
"applicationVersion": {
"version": "1.0.0"
},
"dataSources": {
"invoiceRemote": {
"uri": "V2/Northwind/Northwind.svc/",
"type": "OData",
"settings": {
"odataVersion": "2.0"
}
}
}
},
"sap.ui": {
"technology": "UI5",
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
}
},
"sap.ui5": {
"dependencies": {
"minUI5Version": "1.108.0",
"libs": {
"sap.ui.core": {},
"sap.m": {}
}
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "ui5.walkthrough.i18n.i18n",
"supportedLocales": [""],
"fallbackLocale": ""
}
},
"invoice": {
"dataSource": "invoiceRemote"
}
},
"rootView": {
"viewName": "ui5.walkthrough.view.App",
"type": "XML",
"id": "app"
},
"resources": {
"css": [
{
"uri": "css/style.css"
}
]
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"type": "View",
"viewType": "XML",
"path": "ui5.walkthrough.view",
"controlId": "app",
"controlAggregation": "pages"
},
"routes": [
{
"pattern": "",
"name": "overview",
"target": "overview"
},
{
"pattern": "detail/{invoicePath}",
"name": "detail",
"target": "detail"
}
],
"targets": {
"overview": {
"id": "overview",
"name": "Overview"
},
"detail": {
"id": "detail",
"name": "Detail"
}
}
}
}
}
- "pattern": "detail/{invoicePath}", =》invoicePath 就是要传的参数
2),Detail.view.xml
<mvc:View
controllerName="ui5.walkthrough.controller.Detail"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page
title="{i18n>detailPageTitle}">
<ObjectHeader
intro="{invoice>ShipperName}"
title="{invoice>ProductName}"/>
</Page>
</mvc:View>
- intro="{invoice>ShipperName}" =》通过 invoice 这个变量来访问属性,可以将 invoice理解为表
3),InvoiceList.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator"
], (Controller, JSONModel, Filter, FilterOperator) => {
"use strict";
return Controller.extend("ui5.walkthrough.controller.InvoiceList", {
onInit() {
const oViewModel = new JSONModel({
currency: "EUR"
});
this.getView().setModel(oViewModel, "view");
},
onFilterInvoices(oEvent) {
// build filter array
const aFilter = [];
const sQuery = oEvent.getParameter("query");
if (sQuery) {
aFilter.push(new Filter({
filters: [
new Filter("ProductName", FilterOperator.Contains, sQuery),
new Filter("ShipperName", FilterOperator.Contains, sQuery)
],
and: false // 表示“或”关系(任一字段匹配即可)
}));
}
// filter binding
const oList = this.byId("invoiceList");
const oBinding = oList.getBinding("items");
oBinding.filter(aFilter);
},
onPress(oEvent) {
const oItem = oEvent.getSource();
const oRouter = this.getOwnerComponent().getRouter();
oRouter.navTo("detail", {
invoicePath: window.encodeURIComponent(oItem.getBindingContext("invoice").getPath().substring(1))
});
}
});
});
其实就是改了如下代码:
onPress(oEvent) {
const oItem = oEvent.getSource(); =》oEvent是点击事件对象,通过getSource得到点击行
const oRouter = this.getOwnerComponent().getRouter();
oRouter.navTo("detail", {
invoicePath: window.encodeURIComponent(oItem.getBindingContext("invoice").getPath().substring(1))
=》这句简单来说就是得到 invoice 表中的 path 属性
});
}
=》window.encodeURIComponent 这句的意思是encode 一下(有点儿像加密,就是再编码)
4),Detail.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller"
], (Controller) => {
"use strict";
return Controller.extend("ui5.walkthrough.controller.Detail", {
onInit() {
const oRouter = this.getOwnerComponent().getRouter();
oRouter.getRoute("detail").attachPatternMatched(this.onObjectMatched, this);
},
onObjectMatched(oEvent) {
this.getView().bindElement({
path: "/" + window.decodeURIComponent(oEvent.getParameter("arguments").invoicePath),
model: "invoice"
});
}
});
});
- oRouter.getRoute("detail").attachPatternMatched(this.onObjectMatched, this);
这句指定 detail 的处理函数(回调函数)
- window.decodeURIComponent(oEvent.getParameter("arguments").invoicePath),
这句则把InvoiceList Controller 中的encode给反向 decode,然后得到参数中的 invoicePath值
- model: "invoice" =》这句给该detail 页面的model 取个名,这样页面就可以直接使用
5),运行看结果
为啥这么复杂呢?咱们先在浏览器里看一下decode之后的值
window.decodeURIComponent(oEvent.getParameter("arguments").invoicePath)
"Invoices(CustomerName='Alfreds%20Futterkiste',Discount=0f,OrderID=10835,ProductID=59,ProductName='Raclette%20Courdavault',Quantity=15,Salesperson='Nancy%20Davolio',ShipperName='Federal%20Shipping',UnitPrice=55.0000m)"
手动换个行,看的清楚些
CustomerName='Alfreds%20Futterkiste'
Discount=0f
OrderID=10835
ProductID=59
ProductName='Raclette%20Courdavault'
Quantity=15
Salesperson='Nancy%20Davolio'
ShipperName='Federal%20Shipping'
UnitPrice=55.0000m
看数据的话,跟这个URI 有点儿像
我刚才还合计Freight 怎么没有,应该是Metadata URI 中写上的那些是公开的,没写就没公开
"uri": "https://services.odata.org/V2/northwind/Northwind.svc/Invoices(CustomerName='Alfreds%20Futterkiste',Discount=0f,OrderID=10835,ProductID=59,ProductName='Raclette%20Courdavault',Quantity=15,Salesperson='Nancy%20Davolio',ShipperName='Federal%20Shipping',UnitPrice=55.0000M)",
多显示几个字段试试看,尤其是那些带 %,f,M 之类的
应该是在浏览器端做了什么自动处理了,显示是正常的
下了来看另一个常用的功能,返回上一页(History)。
2,Routing Back and History(路由返回和履历)
1),Detail.view.xml
<mvc:View
controllerName="ui5.walkthrough.controller.Detail"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page
title="{i18n>detailPageTitle}"
showNavButton="true"
navButtonPress=".onNavBack">
<ObjectHeader
intro="{invoice>ShipperName}"
title="{invoice>ProductName}"/>
</Page>
</mvc:View>
- showNavButton="true" =》显示回退按钮
- navButtonPress=".onNavBack"> =》定义回退处理函数
2),Detail.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/routing/History"
], (Controller, History) => {
"use strict";
return Controller.extend("ui5.walkthrough.controller.Detail", {
onInit() {
const oRouter = this.getOwnerComponent().getRouter();
oRouter.getRoute("detail").attachPatternMatched(this.onObjectMatched, this);
},
onObjectMatched(oEvent) {
this.getView().bindElement({
path: "/" + window.decodeURIComponent(oEvent.getParameter("arguments").invoicePath),
model: "invoice"
});
},
onNavBack() {
const oHistory = History.getInstance();
const sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
const oRouter = this.getOwnerComponent().getRouter();
oRouter.navTo("overview", {}, true);
}
}
});
});
- "sap/ui/core/routing/History" =》这个是History 处理类
- Controller里面加了 onNavBack 函数,加了一个判断
onNavBack() {
const oHistory = History.getInstance(); =》得到履历对象,包含所有履历
const sPreviousHash = oHistory.getPreviousHash(); =》找到最近的履历
if (sPreviousHash !== undefined) {
window.history.go(-1); =》如果有履历,则回退到最近的履历
} else {
const oRouter = this.getOwnerComponent().getRouter(); =》没有履历,则迁移到Overview
oRouter.navTo("overview", {}, true);
}
}
另外穿插一点知识:
- onObjectMatched: 函数后面有个警告,Methd xx is possible private
意思是该函数可以设为私有方法
那么该怎么设置成私有方法呢?JS里的通用方法就是加个前缀 _
看这回就没警告了:)
3), 运行看结果
显示了回退按钮
点一下这个 回退按钮,则能回到前页面
其实 window.history.go(-1); 是调用了浏览器的回退功能
那么 什么时候才会出现 没有履历的情况呢?难道本页面是石头缝里蹦出来的?😓
对,你直接在浏览器里面输入的话,浏览器也会显示的,但是没履历。比如这个URL
在浏览器里打开上述URL之前,页面是这样的
然后我直接输入这个URL,浏览器会打开这个界面
如果没有返回处理函数,直接按浏览器上的按钮,会回退到上面的yahoo网址
但是如果有这个返回处理函数,因为对于我们这个localhost 主机来说,它没有履历(石头缝里...),
那么你点回退按钮,就会默认跳到Overview
点回退按钮就退回了 Overview里面,这样就能控制路由,而不是依赖于浏览器的功能
以上就是本篇的全部内容。
更多SAP顾问业务知识请点击下面目录链接或东京老树根的博客主页