运维开发网
广告位招商联系QQ:123077622
 
广告位招商联系QQ:123077622

导航与路由10-

运维开发网 https://www.qedev.com 2020-07-21 13:18 出处:网络 作者:运维开发网整理
Step 10: Implement “Lazy Loading” 通过避免加载不可见的资源来提高浏览器的反映速度,我们称这种方式为延迟加载(lazy loading)。 修改Resume.view.xml <mvc:View controllerName="sap.ui.demo.nav.controller.employee.Resume" xmlns="sap.m"

Step 10: Implement “Lazy Loading”

通过避免加载不可见的资源来提高浏览器的反映速度,我们称这种方式为延迟加载(lazy loading)。

修改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>

为了说明临时加载,我们实现了只有当用户在IconTabBar: Hobbies和Notes中为两个tag选择相应的tab时才加载内容。为每个IconTabFilter都是设置了一个id,以便在之后的路由配置他们。

在resume view中,我们删除了Hobbies和Notes tab的内容,之后我们将用导航特性动态填充它们。

创建ResumeHobbies.view.xml

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

创建ResumeNotes.view.xml

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

修改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*/);
            }
        },
        ...
    });
});

当所选择的tab是Hobbies或Notes的时候,我们通过路由去寻找相应的target,并将他显示在页面。当选择的tab不是Hobbies或Notes时,不会触发路由,所以不用读取页面不会被显示的资源。

这里有效的target是resumeTabHobbies和resumeTabNotes,我们需要在路由中追加这两个target。

修改manifest.json

{
    "_version": "1.12.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" }
            }
        }
    }
}

添加了两个target,resumeTabHobbies和resumeTabNotes,其中的配置信息会覆盖默认的config中的配置信息。

target resumeTabHobbies的parent属性为employeeResume。parent的属性值,是另外一个target值,在这个例子中,确保在resumeTabHobbies显示之前,employeeResume会被加载。这可以看作是一个视图之间的依赖。

通过设置controlId和controlAggregation属性,路由器将视图ResumeHobbies放入ID hobbiesTab的IconTabFilter控件的Aggregation中。

每个target,只能定义一个parent。controlId属性设置为parent view的contriol,这里的parent view 特指target中设置的view。

这样我们就实现了延迟加载,只在第一次被点击的时候进行加载。

导航与路由10-

 

 

Step 11: Assign Multiple Targets

使用一个路由的多个目标,按下按钮会,打开一个包含两个部分的新页面。

修改Home.view.xml

<mvc:View
    controllerName="sap.ui.demo.nav.controller.Home"
    xmlns="sap.m"
    xmlns:mvc="sap.ui.core.mvc">
    <Page title="{i18n>homePageTitle}" class="sapUiResponsiveContentPadding">
        <content>
            <Button id="displayNotFoundBtn" text="{i18n>DisplayNotFound}" press=".onDisplayNotFound" class="sapUiTinyMarginEnd"/>
            <Button id="employeeListBtn" text="{i18n>ShowEmployeeList}" press=".onNavToEmployees" class="sapUiTinyMarginEnd"/>
            <Button id="employeeOverviewBtn" text="{i18n>ShowEmployeeOverview}" press=".onNavToEmployeeOverview" class="sapUiTinyMarginEnd"/>

        </content>
    </Page>
</mvc:View>

添加一个新的按钮,当按钮被点击时,触发onNavToEmployeeOverview。

修改Home.controller.js

sap.ui.define([
    "sap/ui/demo/nav/controller/BaseController"
], function (BaseController) {
    "use strict";
    return BaseController.extend("sap.ui.demo.nav.controller.Home", {
        ...
        onNavToEmployees : function () {
            this.getRouter().navTo("employeeList");
        }, onNavToEmployeeOverview : function () { this.getRouter().navTo("employeeOverview"); }

    });
});

修改manifest.json

{
    "_version": "1.12.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": "",
                "name": "appHome",
                "target": "home"
            }, {
                "pattern": "employees",
                "name": "employeeList",
                "target": "employees"
            }, { "pattern": "employees/overview", "name": "employeeOverview", "target": ["employeeOverviewTop", "employeeOverviewContent"] }, {
                "pattern": "employees/{employeeId}",
                "name": "employee",
                "target": "employee"
            }, {
                "pattern": "employees/{employeeId}/resume:?query:",
                "name": "employeeResume",
                "target": "employeeResume"
            }],
            "targets": {
                ...
                "resumeTabNotes": {
                    "viewId": "resumeNotes",
                    "parent": "employeeResume",
                    "viewPath": "sap.ui.demo.nav.view.employee",
                    "viewName": "ResumeNotes",
                    "controlId": "notesTab",
                    "controlAggregation": "content"
                }, "employeeOverview": { "viewId": "employeeOverview", "viewPath": "sap.ui.demo.nav.view.employee.overview", "viewName": "EmployeeOverview", "viewLevel" : 2 }, "employeeOverviewTop": { "viewId": "employeeOverviewTop", "parent": "employeeOverview", "viewPath": "sap.ui.demo.nav.view.employee.overview", "viewName": "EmployeeOverviewTop", "controlId": "EmployeeOverviewParent", "controlAggregation": "content" }, "employeeOverviewContent": { "viewId": "employeeOverviewContent", "parent": "employeeOverview", "viewPath": "sap.ui.demo.nav.view.employee.overview", "viewName": "EmployeeOverviewContent", "controlId": "EmployeeOverviewParent", "controlAggregation": "content" }

            }
        }
    }
}

添加了新的路由employeeOverview,使用数组同时引用两个target:employeeOverviewTop和employeeOverviewContent。

target employeeOverviewTop和employeeOverviewContent都将target employeeOverview作为parent 引用,因为我们希望将它们都放在parent中。我们还设置了viewPath。

路由器确保在匹配了相应的路由并显示了目标时,除了目标视图外,还加载了父视图。

新建EmployeeOverview.view.xml

<mvc:View controllerName="sap.ui.demo.nav.controller.employee.overview.EmployeeOverview" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">
    <Page id="EmployeeOverviewParent" title="{i18n>EmployeeOverview}" showNavButton="true" navButtonPress=".onNavBack" class="sapUiResponsiveContentPadding">
        <content>
            <!-- inserted by routing -->
        </content>
    </Page>
</mvc:View>

新建EmployeeOverview.controller.js

sap.ui.define([ "sap/ui/demo/nav/controller/BaseController" ], function (BaseController) { "use strict"; return BaseController.extend("sap.ui.demo.nav.controller.employee.overview.EmployeeOverview", { }); });

新建EmployeeOverviewTop.view.xml

<mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" class="sapUiMediumMarginBottom">
    <Title text="{i18n>EmployeeOverviewTop}"/>
</mvc:View>

新建EmployeeOverviewContent.view.xml

<mvc:View
    controllerName="sap.ui.demo.nav.controller.employee.overview.EmployeeOverviewContent"
    xmlns="sap.m"
    xmlns:mvc="sap.ui.core.mvc">
    <Table id="employeesTable"
        items="{/Employees}">
        <headerToolbar>
            <Toolbar>
                <Title text="{i18n>Employees}" level="H2"/>
                <ToolbarSpacer />
                <SearchField id="searchField" search=".onSearchEmployeesTable" width="50%"/>
                <Button icon="sap-icon://sort" press=".onSortButtonPressed"/>
            </Toolbar>
        </headerToolbar>
        <columns>
            <Column id="employeeIDCol"><Text text="{i18n>EmployeeID}"/></Column>
            <Column id="firstNameCol" demandPopin="true"><Text text="{i18n>FirstName}"/></Column>
            <Column id="lastNameCol" demandPopin="true"><Text text="{i18n>LastName}"/></Column>
            <Column id="addressCol" minScreenWidth="Tablet" demandPopin="true"><Text text="{i18n>Address}"/></Column>
            <Column id="cityCol" minScreenWidth="Tablet" demandPopin="true"><Text text="{i18n>City}"/></Column>
            <Column id="regionCol" minScreenWidth="Tablet" demandPopin="true"><Text text="{i18n>Region}"/></Column>
            <Column id="postalCodeCol" minScreenWidth="Tablet" demandPopin="true"><Text text="{i18n>PostalCode}"/></Column>
            <Column id="countryCol" minScreenWidth="Tablet" demandPopin="true"><Text text="{i18n>Country}"/></Column>
            <Column id="homePhoneCol" minScreenWidth="Tablet" demandPopin="true" hAlign="Right"><Text text="{i18n>Phone}"/></Column>
        </columns>
        <items>
            <ColumnListItem>
                <cells>
                    <Text text="{EmployeeID}"/>
                    <Text text="{FirstName}"/>
                    <Text text="{LastName}"/>
                    <Text text="{Address}"/>
                    <Text text="{City}"/>
                    <Text text="{Region}"/>
                    <Text text="{PostalCode}"/>
                    <Text text="{Country}"/>
                    <Text text="{HomePhone}"/>
                </cells>
            </ColumnListItem>
        </items>
    </Table>
</mvc:View>

SearchField允许在表中搜索,Button可以打开一个对话框调整顺序。

新建EmployeeOverviewContent.controller.js

sap.ui.define([
    "sap/ui/demo/nav/controller/BaseController",
    "sap/ui/model/Filter",
    "sap/ui/model/FilterOperator",
    "sap/ui/model/Sorter",
    "sap/m/ViewSettingsDialog",
    "sap/m/ViewSettingsItem"
], function(
    BaseController,
    Filter,
    FilterOperator,
    Sorter,
    ViewSettingsDialog,
    ViewSettingsItem
) {
    "use strict";

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

        onInit: function () {
            this._oTable = this.byId("employeesTable");
            this._oVSD = null;
            this._sSortField = null;
            this._bSortDescending = false;
            this._aValidSortFields = ["EmployeeID", "FirstName", "LastName"];
            this._sSearchQuery = null;

            this._initViewSettingsDialog();
        },

        onSortButtonPressed : function () {
            this._oVSD.open();
        },

        onSearchEmployeesTable : function (oEvent) {
            this._applySearchFilter( oEvent.getSource().getValue() );
        },

        _initViewSettingsDialog : function () {
            this._oVSD = new ViewSettingsDialog("vsd", {
                confirm: function (oEvent) {
                    var oSortItem = oEvent.getParameter("sortItem");
                    this._applySorter(oSortItem.getKey(), oEvent.getParameter("sortDescending"));
                }.bind(this)
            });

            // init sorting (with simple sorters as custom data for all fields)
            this._oVSD.addSortItem(new ViewSettingsItem({
                key: "EmployeeID",
                text: "Employee ID",
                selected: true            // by default the MockData is sorted by EmployeeID
            }));

            this._oVSD.addSortItem(new ViewSettingsItem({
                key: "FirstName",
                text: "First Name",
                selected: false
            }));

            this._oVSD.addSortItem(new ViewSettingsItem({
                key: "LastName",
                text: "Last Name",
                selected: false
            }));
        },

        _applySearchFilter : function (sSearchQuery) {
            var aFilters, oFilter, oBinding;

            // first check if we already have this search value
            if (this._sSearchQuery === sSearchQuery) {
                return;
            }
            this._sSearchQuery = sSearchQuery;
            this.byId("searchField").setValue(sSearchQuery);

            // add filters for search
            aFilters = [];
            if (sSearchQuery && sSearchQuery.length > 0) {
                aFilters.push(new Filter("FirstName", FilterOperator.Contains, sSearchQuery));
                aFilters.push(new Filter("LastName", FilterOperator.Contains, sSearchQuery));
                oFilter = new Filter({ filters: aFilters, and: false });  // OR filter
            } else {
                oFilter = null;
            }

            // update list binding
            oBinding = this._oTable.getBinding("items");
            oBinding.filter(oFilter, "Application");
        },

        /**
         * Applies sorting on our table control.
         * @param {string} sSortField        the name of the field used for sorting
         * @param {string} sortDescending    true or false as a string or boolean value to specify a descending sorting
         * @private
         */
        _applySorter : function (sSortField, sortDescending){
            var bSortDescending, oBinding, oSorter;

            // only continue if we have a valid sort field
            if (sSortField && this._aValidSortFields.indexOf(sSortField) > -1) {

                // convert  the sort order to a boolean value
                if (typeof sortDescending === "string") {
                    bSortDescending = sortDescending === "true";
                } else if (typeof sortDescending === "boolean") {
                    bSortDescending =  sortDescending;
                } else {
                    bSortDescending = false;
                }

                // sort only if the sorter has changed
                if (this._sSortField && this._sSortField === sSortField && this._bSortDescending === bSortDescending) {
                    return;
                }

                this._sSortField = sSortField;
                this._bSortDescending = bSortDescending;
                oSorter = new Sorter(sSortField, bSortDescending);

                // sync with View Settings Dialog
                this._syncViewSettingsDialogSorter(sSortField, bSortDescending);

                oBinding = this._oTable.getBinding("items");
                oBinding.sort(oSorter);
            }
        },

        _syncViewSettingsDialogSorter : function (sSortField, bSortDescending) {
            // the possible keys are: "EmployeeID" | "FirstName" | "LastName"
            // Note: no input validation is implemented here
            this._oVSD.setSelectedSortItem(sSortField);
            this._oVSD.setSortDescending(bSortDescending);
        }

    });

});

修改i18n.properties

EmployeeOverview=Employee Overview ShowEmployeeOverview=Show Employee Overview EmployeeOverviewTop=Employee Overview Top Region=Region EmployeeID=Employee ID Phone=Phone Employees=Employees

Step 12: Make a Search Bookmarkable

扫码领视频副本.gif

0

精彩评论

暂无评论...
验证码 换一张
取 消