ui5_Walkthrough_Step 30: Routing and Navigation 路由和导航

一、基本概念

路由:就是SPA(single page application单页应用)的路径管理器,即URL与页面内容的映射管理器,实现单页无刷新跳转,页面导航,提升用户体验。(类似GPS导航,书本目录

组成部分 说明
路由器(Router) 路由的核心,负责监听URL变化、匹配路由规则并执行相应的导航操作
路由配置(Routes) 定义URL模式与目标视图的映射关系
目标视图(Targets) 定义每个路由目标对应的视图信息,如视图名称、ID、层级等
路由历史(History) 管理浏览器的历史记录,支持前进和后退。
路由事件(Events) 在路由的不同阶段触发的事件,例如路由匹配前、匹配后等

二、练习

新建文件夹29,复制练习Step 28: Integration Test with OPA集成测试OPA 文件夹下内容

2.1 webapp/manifest.json

  • 路由器配置

routing.config部分

javascript 复制代码
"config": {
		"routerClass": "sap.m.routing.Router",  // 路由器类
		"type": "View",                          //目标类型
		"viewType": "XML",                      //视图类型
		"path": "sap.ui5.walkthrough.view",     //视图路径
		"controlId": "app",                    //容器控件ID,视图将被插入哪个容器
		"controlAggregation": "pages"          // 聚合名称,使用容器的哪个聚合属性
	  },
  • 路由规则

routes部分:定义URL与些视图或模块的映射关系

javascript 复制代码
	  "routes": [
		{
		  "pattern": "",
		  "name": "overview",  //路由名称
		  "target": "overview"  //对应目标
		},
		{
		  "pattern": "detail",
		  "name": "detail",
		  "target": "detail"
		}
	  ],

targets部分

viewName为项目中存在的XML视图名称,对应一个具体的视图,比如Overview.view.xml

viewId 为自定义的唯一标识符,用于代码中应用,跳转,判断

javascript 复制代码
 "targets": {
		"overview": {
		  "id": "overview",    //targets 对象内是唯一
		  "name": "Overview"
		},
		"detail": {
		  "id": "detail",
		  "name": "Detail"
		}
	  }

routestargets 的协同工作构成了应用导航的双支柱:

  • targets 定义了"要去哪里"(视图/模块的身份和属性)

  • routes 定义了"如何到达"(URL 路径和组件映射)

**routes中的**target属性即为targets中配置的任意id

javascript 复制代码
{
  "_version": "1.12.0",
  "sap.app": {
    "id": "sap.ui5.walkthrough",
    "type": "application",
    "i18n": "i18n/i18n.properties",
    "title": "{{appTitle}}",
    "description": "{{appDescription}}",
    "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": {
    "rootView": {
      "viewName": "sap.ui5.walkthrough.view.App",
      "type": "XML",
      "async": true,
      "id": "app"
    },
    "resources": {
      "css": [
        {
          "uri": "css/style.css"
        }
      ]
    },
    "dependencies": {
      "minUI5Version": "1.93",
      "libs": {
        "sap.ui.core": {},
        "sap.m": {}
      }
    },
    "models": {
      "i18n": {
        "type": "sap.ui.model.resource.ResourceModel",
        "settings": {
          "bundleName": "sap.ui5.walkthrough.i18n.i18n",
          "supportedLocales": [],
          "fallbackLocale": ""
        }
      },
      
      "invoice": {
			"dataSource": "invoiceRemote"
		}
    },
    "routing": {
	  "config": {
		"routerClass": "sap.m.routing.Router",
		"type": "View",
		"viewType": "XML",
		"path": "sap.ui5.walkthrough.view",
		"controlId": "app",
		"controlAggregation": "pages"
	  },
	  "routes": [
		{
		  "pattern": "",
		  "name": "overview",
		  "target": "overview"
		},
		{
		  "pattern": "detail",
		  "name": "detail",
		  "target": "detail"
		}
	  ],
	  "targets": {
		"overview": {
		  "id": "overview",
		  "name": "Overview"
		},
		"detail": {
		  "id": "detail",
		  "name": "Detail"
		}
	  }
	}
  }
}

2.2 webapp/Component.js

Component.js中新增this.getRouter().initialize(); 初始化路由,路由配置及2.1 manifest.json文件中配置的routing部分,启动路由机制并基于当前URL加载相应的视图。

javascript 复制代码
sap.ui.define(
  [
    "sap/ui/core/UIComponent",
    "sap/ui/model/json/JSONModel",
    "sap/ui/model/resource/ResourceModel",
  ],
  function (UIComponent, JSONModel) {
    "use strict";
    return UIComponent.extend("sap.ui5.walkthrough.Component", {
      metadata: {
        interfaces: ["sap.ui.core.IAsyncContentCreation"],
        manifest: "json",
      },
      init: function () {
        UIComponent.prototype.init.apply(this, arguments);

        var oBundle = this.getModel("i18n").getResourceBundle();
        var oData = {
          recipient: {
            name: oBundle.getText("inputText"),
          },
        };
        var oModel = new JSONModel(oData);
        this.setModel(oModel);
        // create the views based on the url/hash
        this.getRouter().initialize();
      },
    });
  }
);

2.3 webapp/view/Overview.view.xml

这里与2.1中配置 "targets"部分分viewName想对应,及2.2中执行 this.getRouter().initialize();会自动解析当前url匹配路由规则

XML 复制代码
<mvc:View
		controllerName="sap.ui5.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.ui5.walkthrough.view.HelloPanel"/>
			<mvc:XMLView viewName="sap.ui5.walkthrough.view.InvoiceList"/>
		</content>
	</Page>
</mvc:View>

2.4 webapp/view/App.view.xml

Shell控件这里是一个App控件,App页签id为"app",与2.1manifest.json的routes配置中""controlId": "app"相对应

XML 复制代码
<mvc:View
   controllerName="sap.ui5.walkthrough.controller.App"
	xmlns="sap.m"
	xmlns:mvc="sap.ui.core.mvc" 
   displayBlock="true">
 <Shell>
	<App class="myAppDemoWT" id="app"/>
</Shell>
</mvc:View>

2.5 webapp/view/Detail.view.xml

同理manifest.json配置中 "targets"部分"detail"对应的视图,这里需要席间对应的XML视图,即Detail.view.xml

XML 复制代码
<mvc:View
	xmlns="sap.m"
	xmlns:mvc="sap.ui.core.mvc">
	<Page
		title="{i18n>detailPageTitle}">
		<ObjectHeader
			title="Invoice"/>
	</Page>
</mvc:View>

2.6 webapp/i18n/i18n.properties

新增detailPageTitle国际化文本

XML 复制代码
# App Descriptor
apptitle=SAPUI5 Walkthrough Step 30: Routing and Navigation   
appTitle=SAPUI5 Walkthrough Step 30: Routing and Navigation   
appDescription= Descriptor for Applications

homePageTitle=PageTitle
panelTitle1=PanelTitle

ButtonText=Click me
Msg=Hello {0}
inputText= Step 30: Routing and Navigation   
textDesc=Hello
openDialogButtonText=Dialogs and Fragments
helloDialogMsg =helloDialoginf
dialogCloseButtonText=Ok
invoiceListTitle=Invoices
invoiceStatusA=New
invoiceStatusB=In Progress
invoiceStatusC=Done
# Detail Page
detailPageTitle=Walkthrough - Details

2.7 webapp/view/InvoiceList.view.xml

ObjectListItem页签新增 type="Navigation" press="onPress" 属性,实现操作点击列表控件,则触发onPress 函数执行

XML 复制代码
<mvc:View
   controllerName="sap.ui5.walkthrough.controller.InvoiceList"
   xmlns="sap.m"
   xmlns:core="sap.ui.core"
   xmlns:mvc="sap.ui.core.mvc">
   <List
      id="invoiceList"
      headerText="{i18n>invoiceListTitle}"
      class="sapUiResponsiveMargin"
      width="auto"
      mode="SingleSelect"
      selectionChange="onSelectionChange"
      items="{ 
         path : 'invoice>/Invoices',
         sorter: [
            {
                path: 'ShipperName',
                group: true          
            },
            {
                path: 'Quantity',
                descending: true
            }
        ]
            }">
       <headerToolbar>
         <Toolbar>
            <Title text="{i18n>invoiceListTitle}"/>    <!-- 左侧标题 -->
            <ToolbarSpacer/>  <!-- 弹性间距,将后面的控件推到右侧 -->
            <SearchField 
               width="50%" 
               search=".onFilterInvoices"/>  <!-- 搜索事件处理函数 -->
         </Toolbar>
      </headerToolbar>
      <items>
         <ObjectListItem
           title="{invoice>Quantity} x {invoice>ProductName}"
           number="{
                    parts: ['invoice>ExtendedPrice','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'}"
                  state="{ path: 'invoice>Status',formatter: '.formatter.statusState'}"
                  icon="{ path: 'invoice>Status',formatter: '.formatter.statusIcon'}"
                  />
            </firstStatus>
               </ObjectListItem>
            
      </items>
   </List>
</mvc:View>

2.8 webapp/controller/InvoiceList.controller.js

2.7 xml视图中新增了按钮操作,在此处进行onPress函数的实现

复制代码
 this.getOwnerComponent() → 获取当前组件实例
.getRouter() → 获取路由管理器
.navTo("detail") → 导航到名为"detail"的路由
javascript 复制代码
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.ui5.walkthrough.controller.InvoiceList", {
      formatter: formatter,
      //初始化
      onInit: function () {
        var oViewModel = new JSONModel({
          currency: "EUR",
        });
        this.getView().setModel(oViewModel, "view");
      },
      //选择行
      onSelectionChange:function(oEvent){
			var oSelected = oEvent.getSource().getSelectedItem();
			var oList = this.byId("invoiceList");
			var aItems = oList.getItems();
			alert(aItems.indexOf(oSelected));
		},
      //发票列表搜索
      onFilterInvoices: function (oEvent) {
        // build filter array
        const aFilter = [];
        const sQuery = oEvent.getParameter("query");
        if (sQuery) {
          aFilter.push(
            new Filter("ProductName", FilterOperator.Contains, sQuery)
          );
        }

        // filter binding
        const oList = this.byId("invoiceList");
        const oBinding = oList.getBinding("items");
        oBinding.filter(aFilter);
      },
      //详情页面跳转
      onPress: function (oEvent) {
			var oRouter = this.getOwnerComponent().getRouter();
			oRouter.navTo("detail");
		}
    });
  }
);

三、运行结果

http://localhost:8080/webapp/index.html

双击列表任意行

相关推荐
倾心琴心5 天前
【agent辅助pcb routing coding学习】实践3 kicad routing tools 从PCB文件获取了哪些信息
算法·agent·pcb·eda·routing
倾心琴心5 天前
【agent辅助pcb routing coding学习】实践4 kicad pcb 核心类层次关系
算法·agent·pcb·eda·routing
倾心琴心5 天前
【agent辅助pcb routing coding学习】实践1 kicad pcb 格式讲解
算法·agent·pcb·eda·routing
倾心琴心5 天前
【agent辅助pcb routing coding学习】实践5 kicad类按类别理解
算法·agent·pcb·eda·routing
Irene19912 个月前
Vue3 规范推荐的 <script setup> 中书写顺序(附:如何响应路由参数变化)
vue.js·路由
七夜zippoe2 个月前
API网关设计模式实战 Spring Cloud Gateway路由过滤限流深度解析
java·设计模式·gateway·路由·api网关
贾修行2 个月前
.NET MAUI 跨平台开发全栈指南:从零构建现代化多端应用
.net·路由·.net maui
Tipriest_2 个月前
排查一个多网卡的机器上不了网的问题(更改默认路由)
网络·网关·路由·多网卡
一只小阿乐2 个月前
vue 改变查询参数的值
前端·javascript·vue.js·路由·router·网文·未花中文网
noravinsc2 个月前
笔记本电脑如何配置路由,可以同时访问外网和内网
电脑·路由·内外网