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

双击列表任意行

相关推荐
ikkkkkkkl9 天前
计算机网络:网络层
计算机网络·路由·网络层·转发
元亓亓亓12 天前
考研408--计算机网络--day9--路由&RIP&OSPF
网络·计算机网络·路由·rip
未来魔导15 天前
Gin版本的路由总结
开发语言·llm·gin·路由
課代表18 天前
Windows 系统中查看已保存的WiFi密码
网络·windows·wifi·路由·netsh·无线·命令提示符
是罐装可乐1 个月前
前端架构知识体系:通过发布-订阅者模式解耦路由和请求
前端·架构·vue·路由
灵魂学者1 个月前
Vue3.x —— router 路由配置
服务器·前端·vue.js·路由
xiyangyang81101 个月前
Android Navigation 组件(用于Fragment间的跳转)
navigation
一叶难遮天2 个月前
快速入门HarmonyOS应用开发(一)
harmonyos·arkts·arkui·navigation·鸿蒙开发·鸿蒙5.0
RollingPin2 个月前
iOS八股文之 组件化
ios·路由·router·组件化·imp·分层设计