SAPUI5 (19) - 多页面程序及简单的页面导航

Master-detail是一种非常常见的数据关系,比如订单和订单行项目,每个订单包括一个或多个行项目。本篇以供应商清单和供应商明细为例,介绍master-detail的实现方法,并在后续介绍Component的时候,还要用到这个例子,对代码进行重构。我们要实现的功能是:先用一个页面显示供应商清单:

当点击某一个供应商所在行的时候,跳转到供应商明细页面:

并且,点击“返回”按钮的时候,回到概览界面。

如何实现页面跳转

在index.html中定义的app (sap.m.App) 是一个全局对象,通过app.to(sPageId)可以跳转到另外一个页面。

语法to(sPageId, sTransitionName*?*, oData*?*, oTransitionParameters*?*): [sap.m.NavContainer]

Navigates to the next page (with drill-down semantic) with the given (or default) animation. This creates a new history item inside the NavContainer and allows going back.

Note that any modifications to the target page (like setting its title, or anything else that could cause a re-rendering) should be done BEFORE calling to(), in order to avoid unwanted side effects, e.g. related to the page animation.

Available transitions currently include “slide” (default), “fade”, “flip”, and “show”. None of these is currently making use of any given transitionParameters.

Calling this navigation method triggers first the (cancelable) “navigate” event on the NavContainer, then the “beforeHide” pseudo event on the source page and “beforeFirstShow” (if applicable) and"beforeShow" on the target page. Later - after the transition has completed - the “afterShow” pseudo event is triggered on the target page and “afterHide” on the page which has been left. The given data object is available in the “beforeFirstShow”, “beforeShow” and “afterShow” event object as “data” property.

app.back()则跳回到刚才的page:

语法: back(oBackData*?*, oTransitionParameters*?*): [sap.m.NavContainer]

Navigates back one level. If already on the initial page and there is no place to go back, nothing happens.

Calling this navigation method triggers first the (cancelable) “navigate” event on the NavContainer, then the “beforeHide” pseudo event on the source page and “beforeFirstShow” (if applicable) and"beforeShow" on the target page. Later - after the transition has completed - the “afterShow” pseudo event is triggered on the target page and “afterHide” on the page which has been left. The given backData object is available in the “beforeFirstShow”, “beforeShow” and “afterShow” event object as “data” property. The original “data” object from the “to” navigation is also available in these event objects.

使用jsview实现master-detail

我们将通过jsview和xml view两种方式来展示。先介绍jsview的实现。代码的文件结构如下:

json数据

数据存放在json文件中,文件名为data.json。包括两个供应商的信息:

{
    "CountOfSuppliers" : "2",
    "Suppliers" : [
    	{
    		"ID": "1",
    		"Name": "ABC汽车有限公司",
    		"Address": {
    			"Street": "东风大道10号",
    			"City": "武汉",
    			"ZipCode": "430056",
    			"Country": "中国"
    		}
    	},
    	{
    		"ID": "2",
    		"Name": "福建飞驰新能源汽车有限公司",
    		"Address": {
    			"Street": "福建莆田城厢区荔城北大道1999号",
    			"City": "莆田",
    			"ZipCode": "123456",
    			"Country": "中国"
    		}
    	}
    ]
}

Master视图

master视图中,使用sap.m.Table来显示供应商清单。sap.m.Table包含header toolbar,在toolbar中显示供应商的数量:

Master.view.js:

sap.ui.jsview("webapp.view.Master", {

	getControllerName : function() {
		return "webapp.controller.Master";
	},

	createContent : function(oController) {
		
		// 定义table的columns
		var aColumns = [
		    new sap.m.Column({
		    	header: new sap.m.Text({text: "ID"})
		    }),
		    new sap.m.Column({
		    	header: new sap.m.Text({text: "供应商名称"})
		    })
		];
		
 		// 定义template作为line items
		var oTemplate = new sap.m.ColumnListItem({
			type: "Navigation",
			press: [oController.onListPress, oController],
			cells: [
			    new sap.m.ObjectIdentifier({text: "{ID}"}),
			    new sap.m.ObjectIdentifier({text: "{Name}"})
			]
		});
		
		// table的toolbar
		var oHeaderToolbar = new sap.m.Toolbar({
			content: [
			    new sap.m.Title({text: "供应商数量:{/CountOfSuppliers}"})
			]
		});
		
		// table
		var oTable = new sap.m.Table({
			columns: aColumns,
			headerToolbar: oHeaderToolbar
		});
		oTable.bindItems("/Suppliers", oTemplate);
		
		// master page
		var oMasterPage = new sap.m.Page({
			title: "供应商概览",
			content: [oTable]
		});
		
		return oMasterPage;
	}

});

注意sap.m.ColumnListItem的type必须为Navigation,否则不能实现跳转。sap.m.ColumnListItem的press属性设置为一个数组,这种方法能够保证在Controller中,this表示Controller本身,而不是某个控件。

Master Controller

Master.controller.js:

sap.ui.define(
	["sap/ui/core/mvc/Controller"], 
		
	function(Controller){
		"use strict";
		
		return Controller.extend("webapp.controller.Master", {
			onListPress: function(oEvent){
				var sPageId = "detailView";
				oApp.to(sPageId);
				
				var oContext = oEvent.getSource().getBindingContext();
				var oDetailPage = oApp.getPage(sPageId);
				oDetailPage.setBindingContext(oContext);
				
			}
		});
	}
);

在Master controller中,处理ColumnListItem的press事件。当点击的时候,跳转到明细页面,并且将明细页面的BindingContext设置为当前的供应商。比如当选择第一个供应商的时候,oContext为/Suppliers/0,这就是之前文章所介绍的element binding。

Detail View

Detail view负责显示供应商信息,包括供应商ID、名称和地址。
Detail.view.js:

sap.ui.jsview("webapp.view.Detail", {

	getControllerName : function() {
		return "webapp.controller.Detail";
	},

	createContent : function(oController) {
 		var oObjectHeader = new sap.m.ObjectHeader({
 			title: "{Name}",
 			number: "ID: {ID}",
 			attributes: [
 			    new sap.m.ObjectAttribute({
 			    	text: "{Address/Street}, {Address/City}"
 			    })
 			]
 		});
 		
 		var oDetailPage = new sap.m.Page({
 			showNavButton: true,
 			navButtonPress: [oController.onNavPress, oController],
 			title: "供应商明细",
 			content: [oObjectHeader]
 		});
 		
 		return oDetailPage;
	}

});

sap.m.Page中,showNavButton设置为true,就会出现Navigation按钮,点击按钮的event hander通过Controller中onNavPress函数来实现。

Detail Controller

在Detail controller中,增加onNavPress函数,通过app.back()使得能够退回到供应商概览界面。

Detail.controller.js:

sap.ui.define([
         "sap/ui/core/mvc/Controller"
    ], 
    
	function(Controller){
		return Controller.extend("webapp.controller.Detail",{
			onNavPress: function(oEvent){
				oApp.back();
			}
		});
	}
);

最后就是启动的index.html页面,完整代码如下:

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>

		<script src="resources/sap-ui-core.js"
				id="sap-ui-bootstrap"
				data-sap-ui-libs="sap.m"
				data-sap-ui-xx-bindingSyntax="complex"
				data-sap-ui-resourceroots='{"webapp": "./webapp/"}'
				data-sap-ui-theme="sap_bluecrystal">
		</script>		

		<script>
			// application data
			var oModel = new sap.ui.model.json.JSONModel();
			oModel.loadData("webapp/model/data.json");
			sap.ui.getCore().setModel(oModel);
			
			var oApp = new sap.m.App({
				initialPage: "masterView"
			});
			
			var oMasterView = sap.ui.jsview("masterView", "webapp.view.Master");
			var oDetailView = sap.ui.jsview("detailView", "webapp.view.Detail");
			
			oApp.addPage(oMasterView);
			oApp.addPage(oDetailView);
			oApp.placeAt("content");
			
		</script>

	</head>
	<body class="sapUiBody" role="application">
		<div id="content"></div>
	</body>
</html>

index.html的要点:

  • 因为data.json同时被master view和detail view使用,所以我们将Model中的数据交给core对象,这样整个程序都能看到。

  • 在index.html中,需要加载master view和detail view,并且设置两个view的id,这个id是页面跳转的时候需要使用的id。

xml view实现master-detail

因为之前介绍过xml view,所以在这里,主要贴出代码,不再重复介绍。master controller和detail controller的代码都一样,index.html的主要区别是sap.ui.jsview变为sap.ui.xmlview。文件的代码结构:

index.html

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>

		<script src="resources/sap-ui-core.js"
				id="sap-ui-bootstrap"
				data-sap-ui-libs="sap.m"
				data-sap-ui-xx-bindingSyntax="complex"
				data-sap-ui-resourceroots='{"webapp": "./webapp/"}'
				data-sap-ui-theme="sap_bluecrystal">
		</script>		

		<script>
			// application data
			var oModel = new sap.ui.model.json.JSONModel();
			oModel.loadData("webapp/model/data.json");
			sap.ui.getCore().setModel(oModel);
			
			var oApp = new sap.m.App({
				initialPage: "masterView"
			});
			
			var oMasterView = sap.ui.xmlview({
				id: "masterView",
				viewName: "webapp.view.Master"
			});	
			
			var oDetailView = sap.ui.xmlview({
				id: "detailView",
				viewName: "webapp.view.Detail"
			});
			
			oApp.addPage(oMasterView);
			oApp.addPage(oDetailView);
			oApp.placeAt("content");
			
		</script>

	</head>
	<body class="sapUiBody" role="application">
		<div id="content" class="sapUiResponsiveMargin"></div>
	</body>
</html>

Master.view.xml:

<core:View xmlns:core="sap.ui.core" 
	       xmlns:mvc="sap.ui.core.mvc" 
	       xmlns="sap.m"
		controllerName="webapp.controller.Master" 
		xmlns:html="http://www.w3.org/1999/xhtml">
		
	<Page title="供应商概览">
		<content>
			<Table items="{/Suppliers}" >
				<headerToolbar>
					<Toolbar>
						<Title text="供应商数量:{/CountOfSuppliers}" />
					</Toolbar>
				</headerToolbar>
				<columns>
					<Column>
						<header><Text text="ID" /></header>
					</Column>
					<Column>
						<header><Text text="供应商名称" /></header>
					</Column>
				</columns>
				<items>
					<ColumnListItem type="Navigation" press="onListPress">
						<cells>
							<ObjectIdentifier text="{ID}" />
							<ObjectIdentifier text="{Name}" />
						</cells>
					</ColumnListItem>
				</items>
				
			</Table>
		</content>
	</Page>	
</core:View>

Detail.view.xml:

<core:View xmlns:core="sap.ui.core" 
           xmlns:mvc="sap.ui.core.mvc" 
           xmlns="sap.m"
		controllerName="webapp.controller.Detail" 
		xmlns:html="http://www.w3.org/1999/xhtml">
		
	<Page title="供应商明细" showNavButton="true" navButtonPress="onNavPress">
		<content>
			<ObjectHeader title="{Name}" 
			    number="ID: {ID}">
			    <attributes>
			    	<ObjectAttribute text="{Address/Street}, {Address/City}" />
			    </attributes>
			
			</ObjectHeader>
		</content>
	</Page>
	
</core:View>
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值