이번 튜토리얼에선 커스텀 전환 애니메이션이있는 페이지로 이동하는 방법을 설명한다.
앞으로 및 뒤로 탐색 모두 "flip"전환을 사용하지만 방향이 다르게 구성한다.
employee view에서 특정 직원의 이력서 데이터를 표시하는 페이지로 넘겨주는 간단한 링크를 만든다.
뒤로 버튼을 누르면 반전 된 flip 전환과 함께 employee view로 돌아간다.

Preview

08_preview1.png

08_preview2.png

08_preview3.png

Coding

Routing and Navigation - Step 8.

webapp/view/employee/Employee.view.xml

<mvc:View
    controllerName="sap.ui.demo.nav.controller.employee.Employee"
    xmlns="sap.m"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:f="sap.ui.layout.form"
    busyIndicatorDelay="0">
    <Page
        id="employeePage"
        title="{i18n>EmployeeDetailsOf} {FirstName} {LastName}"
        showNavButton="true"
        navButtonPress=".onNavBack"
        class="sapUiResponsiveContentPadding">
        <content>
            <Panel
                id="employeePanel"
                width="auto"
                class="sapUiResponsiveMargin sapUiNoContentPadding">
                <headerToolbar>
                    <Toolbar>
                        <Title text="{i18n>EmployeeIDColon} {EmployeeID}" level="H2"/>
                        <ToolbarSpacer />
                        <Link text="{i18n>FlipToResume}" tooltip="{i18n>FlipToResume.tooltip}" press=".onShowResume"/>
                    </Toolbar>
                </headerToolbar>
                <content>
                    ...
                </content>
            </Panel>
        </content>
    </Page>
</mvc:View>

해당 view에서 sap.m에 있는 Link 컨트롤을 추가하여 현재 표시된 직원의 이력서로 이동하게 한다.

webapp/controller/employee/Employee.controller.js

sap.ui.define([
    "sap/ui/demo/nav/controller/BaseController"
], function (BaseController) {
    "use strict";

    return BaseController.extend("sap.ui.demo.nav.controller.employee.Employee", {

        onInit: function () {
            var oRouter = this.getRouter();

            oRouter.getRoute("employee").attachMatched(this._onRouteMatched, this);

            // Hint: we don't want to do it this way
            /*
             oRouter.attachRouteMatched(function (oEvent){
                 var sRouteName, oArgs, oView;

                 sRouteName = oEvent.getParameter("name");
                 if (sRouteName === "employee"){
                     this._onRouteMatched(oEvent);
                 }
             }, this);
             */

        },

        _onRouteMatched : function (oEvent) {
            var oArgs, oView;

            oArgs = oEvent.getParameter("arguments");
            oView = this.getView();

            oView.bindElement({
                path : "/Employees(" + oArgs.employeeId + ")",
                events : {
                    change: this._onBindingChange.bind(this),
                    dataRequested: function (oEvent) {
                        oView.setBusy(true);
                    },
                    dataReceived: function (oEvent) {
                        oView.setBusy(false);
                    }
                }
            });
        },

        _onBindingChange : function (oEvent) {
            // No data for the binding
            if (!this.getView().getBindingContext()) {
                this.getRouter().getTargets().display("notFound");
            }
        },

        onShowResume : function (oEvent) {
            var oCtx = this.getView().getBindingContext();

            this.getRouter().navTo("employeeResume", {
                employeeId : oCtx.getProperty("EmployeeID")
            });
        }

    });

});

Employee.controller에서 onShowResume 핸들러를 추가하여 Flip to Resume 링크로 들어가게 한다.
핸들러는 새로운 라우터인 employeeResume으로 이동을 시키고 view의 bound context로 EmployeeID를 파라미터로 넘겨준다.

webapp/manifest.json

{
    ...,
    "sap.ui5": {
        ...,
        "routing": {
            "config": {
                "routerClass": "sap.m.routing.Router",
                "viewType": "XML",
                "viewPath": "sap.ui.demo.nav.view",
                "controlId": "app",
                "controlAggregation": "pages",
                "transition": "slide",
                "bypassed": {
                    "target": "notFound"
                }
            },
            "routes": [{
                "pattern": "",
                "name": "appHome",
                "target": "home"
            }, {
                "pattern": "employees",
                "name": "employeeList",
                "target": "employees"
            }, {
                "pattern": "employees/{employeeId}",
                "name": "employee",
                "target": "employee"
            }, {
                "pattern": "employees/{employeeId}/resume",
                "name": "employeeResume",
                "target": "employeeResume"
            }],
            "targets": {
                "home": {
                    "viewId": "home",
                    "viewName": "Home",
                    "viewLevel" : 1
                },
                "notFound": {
                    "viewId": "notFound",
                    "viewName": "NotFound",
                    "transition": "show"
                },
                "employees": {
                    "viewId": "employees",
                    "viewPath": "sap.ui.demo.nav.view.employee",
                    "viewName": "EmployeeList",
                    "viewLevel" : 2
                },
                "employee": {
                    "viewId": "employee",
                    "viewName": "employee.Employee",
                    "viewLevel" : 3
                },
                "employeeResume": {
                    "viewId": "resume",
                    "viewName": "employee.Resume",
                    "viewLevel" : 4,
                    "transition": "flip"
                }
            }
        }
    }
}

descriptor에서 target을 참조하는 새 라우트인 employeeResume를 추가한다. 라우트의 pattern은 {employeeId}를 필수 매개 변수로 한다.
target은 employee.Resume view를 참조한다. 대상의 viewLevel은 4로 설정한다.

note:

  • slide
  • flip
  • show
  • fade
    사용자는 sap.m.NavContainer control을 상속받아 다른 전환 애니메이션을 구성할 수 있다.

webapp/view/employee/Resume.view.xml (New)

<mvc:View
    controllerName="sap.ui.demo.nav.controller.employee.Resume"
    xmlns="sap.m"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:f="sap.ui.layout.form"
    busyIndicatorDelay="0">
    <Page
        title="{i18n>ResumeOf} {FirstName} {LastName}"
        id="employeeResumePage"
        showNavButton="true"
        navButtonPress="onNavBack"
        class="sapUiResponsiveContentPadding">
        <content>
            <IconTabBar
                id="iconTabBar"
                class="sapUiResponsiveContentPadding"
                binding="{Resume}">
                <items>
                    <IconTabFilter id="infoTab" text="{i18n>Info}" key="Info">
                        <Text text="{Information}" />
                    </IconTabFilter>
                    <IconTabFilter id="projectsTab" text="{i18n>Projects}" key="Projects">
                        <mvc:XMLView viewName="sap.ui.demo.nav.view.employee.ResumeProjects"></mvc:XMLView>
                    </IconTabFilter>
                    <IconTabFilter id="hobbiesTab" text="{i18n>Hobbies}" key="Hobbies">
                        <Text text="{Hobbies}" />
                    </IconTabFilter>
                    <IconTabFilter id="notesTab" text="{i18n>Notes}" key="Notes">
                        <Text text="{Notes}" />
                    </IconTabFilter>
                </items>
            </IconTabBar>
        </content>
    </Page>
</mvc:View>

webapp/view/employee 경로에 해당 파일을 생성한다. view는 IconTabBar 컨트롤을 사용하여 이력서를 표시한다.
해당 바인딩 속성은 {Resume}으로 Employee.json에 있는 Resume 키를 받아 설정이 된다.
IconTabBar는 네개의 탭이 있. 그중 3개는 text 컨트롤을 사용하여 데이터를 표시하지만 projects 탭은 클릭시 xml view로 로드된다.

webapp/controller/employee/Resume.controller.js (New)

sap.ui.define([
    "sap/ui/demo/nav/controller/BaseController"
], function (BaseController) {
    "use strict";
    return BaseController.extend("sap.ui.demo.nav.controller.employee.Resume", {
     onInit: function () {
            var oRouter = this.getRouter();
            oRouter.getRoute("employeeResume").attachMatched(this._onRouteMatched, this);
        },
        _onRouteMatched : function (oEvent) {
            var oArgs, oView;
            oArgs = oEvent.getParameter("arguments");
            oView = this.getView();
            oView.bindElement({
                path : "/Employees(" + oArgs.employeeId + ")",
                events : {
                    change: this._onBindingChange.bind(this),
                    dataRequested: function (oEvent) {
                        oView.setBusy(true);
                    },
                    dataReceived: function (oEvent) {
                        oView.setBusy(false);
                    }
                }
            });
        },
        _onBindingChange : function (oEvent) {
            // No data for the binding
            if (!this.getView().getBindingContext()) {
                this.getRouter().getTargets().display("notFound");
            }
        }
    });
});

webapp/controller/employee 경로에 해당 파일을 만든다. 이 컨트롤러는 employeeResume 라우트가 일치할때 올바른 employee를 view에 바인딩 한다.
이전 step 7과 마찬가지로 user를 찾을 수 없는 경우에는 _onBindingChange 함수에서 notFound target을 표시한다.

webapp/view/employee/ResumeProjects.view.xml (New)

<mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">
    <Text text="{Projects}" />
</mvc:View>

해당 view는 컨트롤러가 없다. 선택된 employee의 프로젝트 텍스트가 있는 텍스트 컨트롤만 표시한다.

webapp/i18n/i18n.properties

...
ResumeOf=Resume of
Info=Info
Projects=Projects
Hobbies=Hobbies
Notes=Notes
FlipToResume=Flip to Resume
FlipToResume.tooltip=See the resume of this employee