이전 단계에서 App의 view에서 page를 직접 정의하여 App 로드 시 표시 되도록 했다.
컨텐츠를 분리하여 별도의 페이지에 넣어 더 많은 기능을 추가하도록 라우터 기능을 알아보자
이제 SAPUI5 router 클래스를 사용하여 페이지를 로드하고 자동으로 URL을 업데이트한다.
App의 routing 구성을 지정하고 App의 각 page에 대해 별도의 view를 만든 다음 navigation 이벤트를 트리거 하여 view를 연결할 것이다.
{
"_version": "1.12.0",
…
"sap.ui5": {
…
"models": {
…
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"viewPath": "sap.ui.demo.walkthrough.view",
"controlId": "app",
"controlAggregation": "pages",
"async": true
},
"routes": [
{
"pattern": "",
"name": "overview",
"target": "overview"
},
{
"pattern": "detail",
"name": "detail",
"target": "detail"
}
],
"targets": {
"overview": {
"viewId": "overview",
"viewName": "Overview"
},
"detail": {
"viewId": "detail",
"viewName": "Detail"
}
}
}
}
}
새로운 routing section을 descriptor의 sap.ui5 부분에 추가한다.
App의 routing 및 navigation structure를 정의하는 세 개의 하위 section이 있다.
1) config
이 섹션에는 모든 routes 및 targets에 적용되는
global router
구성 및 기본값이 포함된다.
router class가 App의 view어디에 위치하는지 정의한다.
자동으로 view를 load하고 표시하기 위해 page를 표시하는 데 사용되는 control과 새 page가 표시 될 때 채워지는 aggregation를 지정한다.
2) routes
각 route는 name pattern 및 1개 이상의 navigate용
target
을 지정한다. 이는 route가 hit된 경우 호출된다.
pattern
은path
와 일치하는 URL 부분이다.
우리App에는 두 개의 route를 정의한다.
첫 번째 route는 이전 단계의 내용으로 overview 페이지를 표시하는 기본 경로이고 두 번째 route는 새 페이지를 표시하는 detail route이다.
(여기에서는 URL pattern을 detail로 설정한다.)
3) targets
target은 표시되는
view
를 정의한다.
이 view는 하나 이상의 route와 연관되며 App 내에서 수동으로 표시 할 수도 있다.
target이 표시 될 때마다 해당 view가 load되어 App에 표시된다.
우리의 App 프로그램에서는 target name에 해당하는view name
을 가진 두 개의 target을 정의한다.
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel",
"./controller/HelloDialog"
], function (UIComponent, JSONModel, HelloDialog) {
"use strict";
return UIComponent.extend("sap.ui.demo.walkthrough.Component", {
metadata: {
manifest: "json"
},
init: function () {
…
// set dialog
this._helloDialog = new HelloDialog(this.getRootControl());
// create the views based on the url/hash
this.getRouter().initialize();
},
});
exit : function () {
this._helloDialog.destroy();
delete this._helloDialog;
},
openHelloDialog : function () {
this._helloDialog.open();
}
});
});
Component의 init method에서 router를 초기화하는 호출을 추가한다.
router를 수동으로 인스턴스화 할 필요는 없으며 AppDescriptor 구성에 따라 자동으로 instance되고 Component에 할당된다.
Router를 초기화하면 현재 URL을 알 수 있어 해당view를 자동으로 load한다.
이 작업은 AppDescriptor에서 구성된 route 및 target을 사용하여 수행된다.
경로에 도달하면 해당 대상의 view가 load되고 표시된다.
<mvc:View
controllerName="sap.ui.demo.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.ui.demo.walkthrough.view.HelloPanel"/>
<mvc:XMLView viewName="sap.ui.demo.walkthrough.view.InvoiceList"/>
</content>
</Page>
</mvc:View>
이전 App view의 내용을 새로운 view인 Overview로 이동한다.
2개의 view App, Overview의 controller로 동일한 sap.ui.demo.walkthrough.controller.App
을 재사용한다.
그러나 해당 controller의 두 instance는 runtime에 각각 instance화 된다.
일반적으로 controller를 참조하는 각 view에 대해 하나의 controller instance가 instance화 된다.
<mvc:View
controllerName="sap.ui.demo.walkthrough.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
displayBlock="true">
<Shell>
<App class="myAppDemoWT" id="app"/>
</Shell>
</mvc:View>
이제 app view는 빈 앱 태그 만 포함된다. 라우터는 자동으로 현재 URL에 해당하는 view를 app 컨트롤에 추가한다.
라우터는 App Descriptor의 controlId : "app"
속성에 해당하는 ID로 app 컨트롤을 식별합니다.
<mvc:View
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page
title="{i18n>detailPageTitle}">
<ObjectHeader
title="Invoice"/>
</Page>
</mvc:View>
이제 detail view에 대한 두 번째 view를 추가한다.
여기에는 오직 텍스트 invoice를 표시하는 ObjectHeader 컨트롤과 page만 작성한다.
# Invoice List
invoiceListTitle=Invoices
invoiceStatusA=New
invoiceStatusB=In Progress
invoiceStatusC=Done
# Detail Page
detailPageTitle=Walkthrough - Details
<mvc:View
controllerName="sap.ui.demo.walkthrough.controller.InvoiceList"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<List …>
…
<items>
<ObjectListItem
title="{invoice>Quantity} x {invoice>ProductName}"
number="{
parts: [{path: 'invoice>ExtendedPrice'}, {path: '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'
}"/>
</firstStatus>
</ObjectListItem>
</items>
</List>
</mvc:View>
Invoice List view에서 Item에 press event를 추가하고 실제로 item을 click 할 수 있도록 type
을 Navigation
으로 설정한다.
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.ui.demo.walkthrough.controller.InvoiceList", {
…
onPress: function (oEvent) {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("detail");
}
});
});
event handler function을 invoice list의 controller에 추가한다.
이제 Invoice list의 item을 click하여 detail 정보 페이지로 이동할 수 있도록
helper 메소드 sap.ui.core.UIComponent.getRouterFor(this)
를 호출하여 Application 의 router 인스턴스에 액세스한다.
Router에서 우리는 navTo
method를 호출하여 routing 설정에서 지정한 detail 경로를 탐색한다.