이전 튜토리얼에서는 tab을 사용하여 데이터를 표시하는 Resume view를 구현했다.
하지만 현재 표시되는 tab에 관계없이 tab의 전체 내용이 한 번에 로드가 된다.
App의 성능을 높으기 위해 사용자가 요청할 때만 view와 data를 로드하는 "lazy loading"기능을 구현해보자

Preview

10_preview.png

Coding

Routing and Navigation - Step 10 .

webapp/view/employee/Resume.view.xml

<mvc:View
    controllerName="sap.ui.demo.nav.controller.employee.Resume"
    xmlns="sap.m"
    xmlns:mvc="sap.ui.core.mvc">
    <Page
        title="{i18n>ResumeOf} {FirstName} {LastName}"
        id="employeeResumePage"
        showNavButton="true"
        navButtonPress=".onNavBack">
        <content>
            <IconTabBar
                id="iconTabBar"
                headerBackgroundDesign="Transparent"
                class="sapUiResponsiveContentPadding"
                binding="{Resume}"
                select=".onTabSelect"
                selectedKey="{view>/selectedTabKey}">
                <items>
                    <IconTabFilter id="infoTab" text="{i18n>tabInfo}" 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">
                        <!-- place content via lazy loading -->
                    </IconTabFilter>
                    <IconTabFilter id="notesTab" text="{i18n>Notes}" key="Notes">
                        <!-- place content via lazy loading -->
                    </IconTabFilter>
                </items>
            </IconTabBar>
        </content>
    </Page>
</mvc:View>

lazy loading을 설명하기 위해 사용자가 IconTabBar 컨드롤중 Hobbies, Notes 탭을 선택한 경우만 content가 동적으로 로드 되도록 테스트 해보자

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

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

webapp/view/employee 경로에 해당 파일을 새ㅐㅇ성하고 이전 resume view에 있던 tab 내용들을 해당 파일로 옮긴다.
아직은 추가적인 로직이 필요벗기 때문에 컨트롤러는 만들지 않는다.
이 view는 lazy load시 탐새ㅐㄱ되어 Hobbies 탭에 내용이 배치된다.

webapp/controller/employee/Resume.controller.js

sap.ui.define([
    "sap/ui/demo/nav/controller/BaseController",
    "sap/ui/model/json/JSONModel"
], function (BaseController, JSONModel) {
    "use strict";
    var _aValidTabKeys = ["Info", "Projects", "Hobbies", "Notes"];
    return BaseController.extend("sap.ui.demo.nav.controller.employee.Resume", {
        ...
        _onRouteMatched : function (oEvent) {
            var oArgs, oView, oQuery;
            oArgs = oEvent.getParameter("arguments");
            oView = this.getView();
            oView.bindElement({
                ...
            });
            oQuery = oArgs["?query"];
            if (oQuery && _aValidTabKeys.indexOf(oQuery.tab) > -1){
                oView.getModel("view").setProperty("/selectedTabKey", oQuery.tab);
                // support lazy loading for the hobbies and notes tab
                if (oQuery.tab === "Hobbies" || oQuery.tab === "Notes"){
                    // the target is either "resumeTabHobbies" or "resumeTabNotes"
                    this.getRouter().getTargets().display("resumeTab" + oQuery.tab);
                }

            } else {
                // the default query param should be visible at all time
                this.getRouter().navTo("employeeResume", {
                    employeeId : oArgs.employeeId,
                    query: {
                        tab : _aValidTabKeys[0]
                    }
                },true /*no history*/);
            }
        },
        ...
    });
});

Resume 컨트롤에서 _onRouteMatched함수에 Hobbies탭과 Notes 탭의 유효성 검새 로직을 추가한다.
selectedTabKey가 Hobbies, Notes 탭과 일치하는 경우 this.getRouter().getTargets().display("resumeTab" + oQuery.tab);을 호출하여
해당 target을 수동으로 표시한다.

webapp/manifest.json

{
    "_version": "1.8.0",
    "sap.app": {
        ...
    },
    "sap.ui": {
        ...
    },
    "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": "employees/{employeeId}/resume:?query:",
                "name": "employeeResume",
                "target": "employeeResume"
            }],
            "targets": {
                ...
                "employeeResume": {
                    "viewId": "resume",
                    "viewName": "employee.Resume",
                    "viewLevel" : 4,
                    "transition": "flip"
                },
                "resumeTabHobbies": {
                    "viewId": "resumeHobbies",
                    "parent": "employeeResume",
                    "viewPath": "sap.ui.demo.nav.view.employee",
                    "viewName": "ResumeHobbies",
                    "controlId": "hobbiesTab",
                    "controlAggregation": "content"
                },
                "resumeTabNotes": {
                    "viewId": "resumeNotes",
                    "parent": "employeeResume",
                    "viewPath": "sap.ui.demo.nav.view.employee",
                    "viewName": "ResumeNotes",
                    "controlId": "notesTab",
                    "controlAggregation": "content"
                }
            }
        }
    }
}

descriptor에 resumeHobbies, resumeNotes 타겟을 정의하여 target을 IconTabBar 컨트롤에 local로 표시한다.

resumeTabHobbies target은 employeeResume로 parent 속성을 정의한다. parent속성은 다른 target의 이름을 사용한다.
resumeTabHobbies target이 로드되기 전 부모의 employeeResume의 view가 먼저 로드 되는지 확인한다.
controlId속성과 controlAggregation속성을 추가하여ㅛ 라우터에 ID 값을 부여하여 content aggregation에 ResumeHobbies view를 배치한다.

note:
각 target은 parent를 하나만 정의 할 수 있다. 이것은 각 control이 하나의 상위 컨트롤(getParent () of sap.ui.base.ManagedObject를 사용하여 액세스 할 수있는)만 가질 수있는 SAPUI5 컨트롤 tree와 유사하다.
controlId 속성은 항상 부모 대상에서 지정된 부모 view 내부의 컨트롤을 참조한다.

Hobbies target 설정처럼 resumeTabNotes를 동일하게 설정한다.

이제 Hobbies, Notes 탭에 lazy loading을 구현했다. 두 탭은 라우팅 구성에 의해 관리되며 처음 클릭시에 로드가 된다.
테스트를 위해 브라우저의 개발자 모드로 network 탭을 열어 탭을 클릭하면 해당 view xml이 로드되는걸 알 수 있다.

10_preview2.png