Master-detail是一種非常常見的數(shù)據(jù)關系挽拔,比如訂單和訂單行項目,每個訂單包括一個或多個行項目但校。本篇以供應商清單和供應商明細為例螃诅,介紹master-detail的實現(xiàn)方法,并在后續(xù)介紹Component的時候状囱,還要用到這個例子术裸,對代碼進行重構(gòu)。我們要實現(xiàn)的功能是:先用一個頁面顯示供應商清單:
當點擊某一個供應商所在行的時候亭枷,跳轉(zhuǎn)到供應商明細頁面:
并且袭艺,點擊“返回”按鈕的時候,回到概覽界面叨粘。
如何實現(xiàn)頁面跳轉(zhuǎn)
在index.html中定義的app (sap.m.App
) 是一個全局對象匹表,通過app.to(sPageId)
可以跳轉(zhuǎn)到另外一個頁面。
語法: 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實現(xiàn)master-detail
我們將通過jsview和xml view兩種方式來展示宣鄙。先介紹jsview的實現(xiàn)袍镀。代碼的文件結(jié)構(gòu)如下:
json數(shù)據(jù)
數(shù)據(jù)存放在json文件中,文件名為data.json
冻晤。包括兩個供應商的信息:
{
"CountOfSuppliers" : "2",
"Suppliers" : [
{
"ID": "1",
"Name": "ABC汽車有限公司",
"Address": {
"Street": "東風大道10號",
"City": "武漢",
"ZipCode": "430056",
"Country": "中國"
}
},
{
"ID": "2",
"Name": "福建飛馳新能源汽車有限公司",
"Address": {
"Street": "福建莆田城廂區(qū)荔城北大道1999號",
"City": "莆田",
"ZipCode": "123456",
"Country": "中國"
}
}
]
}
Master視圖
master視圖中伍伤,使用sap.m.Table
來顯示供應商清單响疚。sap.m.Table
包含header toolbar,在toolbar中顯示供應商的數(shù)量:
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: "供應商數(shù)量:{/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,否則不能實現(xiàn)跳轉(zhuǎn)袋励。sap.m.ColumnListItem
的press屬性設置為一個數(shù)組崖瞭,這種方法能夠保證在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事件歼捏。當點擊的時候,跳轉(zhuǎn)到明細頁面笨篷,并且將明細頁面的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
,就會出現(xiàn)Navigation按鈕悯蝉,點擊按鈕的event hander通過Controller中onNavPress
函數(shù)來實現(xiàn)归形。
Detail Controller
在Detail controller中,增加onNavPress
函數(shù)泉粉,通過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中的數(shù)據(jù)交給core對象,這樣整個程序都能看到窟感。在index.html中讨彼,需要加載master view和detail view,并且設置兩個view的id柿祈,這個id是頁面跳轉(zhuǎn)的時候需要使用的id哈误。
xml view實現(xiàn)master-detail
因為之前介紹過xml view,所以在這里躏嚎,主要貼出代碼蜜自,不再重復介紹。master controller和detail controller的代碼都一樣卢佣,index.html的主要區(qū)別是sap.ui.jsview
變?yōu)?code>sap.ui.xmlview重荠。文件的代碼結(jié)構(gòu):
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="供應商數(shù)量:{/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>