이전 단계에서 App의 view에서 page를 직접 정의하여 App 로드 시 표시 되도록 했다.
컨텐츠를 분리하여 별도의 페이지에 넣어 더 많은 기능을 추가하도록 라우터 기능을 알아보자

이제 SAPUI5 router 클래스를 사용하여 페이지를 로드하고 자동으로 URL을 업데이트한다.
App의 routing 구성을 지정하고 App의 각 page에 대해 별도의 view를 만든 다음 navigation 이벤트를 트리거 하여 view를 연결할 것이다.

Preview

31_preview.png

Coding

Walkthrough - Step 31.

webapp/manifest.json

{
  "_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

이 섹션에는 모든 routestargets에 적용되는 global router 구성 및 기본값이 포함된다.
router class가 App의 view어디에 위치하는지 정의한다.
자동으로 view를 load하고 표시하기 위해 page를 표시하는 데 사용되는 control과 새 page가 표시 될 때 채워지는 aggregation를 지정한다.

2) routes
각 route는 name pattern 및 1개 이상의 navigate용 target을 지정한다. 이는 route가 hit된 경우 호출된다.
patternpath와 일치하는 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을 정의한다.

webapp/Component.js

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되고 표시된다.

webapp/view/Overview.view.xml (New)

<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화 된다.

webapp/view/App.view.xml

<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 DescriptorcontrolId : "app"속성에 해당하는 ID로 app 컨트롤을 식별합니다.

webapp/view/Detail.view.xml (New)

<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만 작성한다.

webapp/i18n/i18n.properties

# Invoice List
invoiceListTitle=Invoices
invoiceStatusA=New
invoiceStatusB=In Progress
invoiceStatusC=Done

# Detail Page
detailPageTitle=Walkthrough - Details

webapp/view/InvoiceList.view.xml

<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 할 수 있도록 typeNavigation으로 설정한다.

webapp/controller/InvoiceList.controller.js

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 경로를 탐색한다.

Conventions

  • manifest.json에 라우팅 구성을 정의한다.

Routing and Navigation

Tutorial: Navigation and Routing

API Reference: sap.m.routing.Router