导航与路由10-17(渣翻完结)

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。

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

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

在url中加入书签标记

修改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:?query:",
                "name": "employeeOverview",
                "target": ["employeeOverviewTop", "employeeOverviewContent"]

            }, {
                "pattern": "employees/{employeeId}",
                "name": "employee",
                "target": "employee"
            }, {
                "pattern": "employees/{employeeId}/resume:?query:",
                "name": "employeeResume",
                "target": "employeeResume"
            }],
            "targets": {
                ...
            }
        }
    }
}

为了使搜索的内容可以标记,应该考虑相应的路由pattern如果记载搜索的内容。所以使用/#/employees/overview?search=mySearchQueryString这种格式来标记搜索的内容。追加一个:?query:参数到路由employeeOverview。

要用search作为搜索内容的标记。

修改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 () {
            var oRouter = this.getRouter();

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


            this._initViewSettingsDialog();

            // make the search bookmarkable
            oRouter.getRoute("employeeOverview").attachMatched(this._onRouteMatched, this);

        },

        _onRouteMatched : function (oEvent) {
            // save the current query state
            this._oRouterArgs = oEvent.getParameter("arguments");
            this._oRouterArgs.query = this._oRouterArgs["?query"] || {};

            if (this._oRouterArgs.query) {

                // search/filter via URL hash
                this._applySearchFilter(this._oRouterArgs.query.search);

            }
        },


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

        onSearchEmployeesTable : function (oEvent) {
            var oRouter = this.getRouter();
            // update the hash with the current search term
            this._oRouterArgs.query.search = oEvent.getSource().getValue();
            oRouter.navTo("employeeOverview",this._oRouterArgs, true /*no history*/);
        },
        ...
    });
});

在controller中处理路由中的查询参数。

在onInit函数中,监听路由,如果路由为employeeOverview,则触发事件_onRouteMatched。通过接收到的event,获取到路由的参数。在获取到的参数中,会包含一个?query属性,该属性会定义指向的搜索内容。

如果有该属性,那么将其保存到 this._oRouterArgs.query中,否则设置为空。如果query上有search的内容,那么将调用this._applySearchFilter(this._oRouterArgs.query.search)来进行查询。

在onSearchEmployeesTable函数中取得在检索框中输入的内容,并且放入路由的参数中,用于在之后的页面中进行传递。

Step 13: Make Table Sorting Bookmarkable

在url中标记表的排序状态

修改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 () {
            ...
        },
        _onRouteMatched : function (oEvent) {
            // save the current query state
            this._oRouterArgs = oEvent.getParameter("arguments");
            this._oRouterArgs.query = this._oRouterArgs["?query"] || {};
            delete this._oRouterArgs["?query"];
            if (this._oRouterArgs.query) {
                // search/filter via URL hash
                this._applySearchFilter(this._oRouterArgs.query.search);
                // sorting via URL hash
                this._applySorter(this._oRouterArgs.query.sortField, this._oRouterArgs.query.sortDescending);
            }
        },
        ...
        _initViewSettingsDialog : function () {
            var oRouter = this.getRouter();
            this._oVSD = new sap.m.ViewSettingsDialog("vsd", {
                confirm: function (oEvent) {
                    var oSortItem = oEvent.getParameter("sortItem");
            var oRouter = this.getRouter();
this._oRouterArgs.query.sortField = oSortItem.getKey(); this._oRouterArgs.query.sortDescending = oEvent.getParameter("sortDescending"); oRouter.navTo("employeeOverview",this._oRouterArgs, true /*without history*/); }.bind(this) }); ... }, ... }); });

与step12类似,在query中追加了两个参数,sortField与sortDescending。在_onRouteMatched函数中,从url中获取这两个参数。用来进行下一步的处理。

在_initViewSettingsDialog函数中,当confirm方法触发时,获取参数,并将参数放入路由中。

Step 14: Make Dialogs Bookmarkable

记录对话框是否表示的状态,与step12,13类似。

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 () {
            ...
        },
        _onRouteMatched : function (oEvent) {
            // save the current query state
            this._oRouterArgs = oEvent.getParameter("arguments");
            this._oRouterArgs.query = this._oRouterArgs["?query"] || {};
            delete this._oRouterArgs["?query"];
            if (this._oRouterArgs.query) {
                // search/filter via URL hash
                this._applySearchFilter(this._oRouterArgs.query.search);
                // sorting via URL hash
                this._applySorter(this._oRouterArgs.query.sortField, this._oRouterArgs.query.sortDescending);
                // show dialog via URL hash
                if (!!this._oRouterArgs.query.showDialog) {
                    this._oVSD.open();
                }
            }
        },
        onSortButtonPressed : function (oEvent) {
            var oRouter = this.getRouter();
            this._oRouterArgs.query.showDialog = 1;
            oRouter.navTo("employeeOverview",this._oRouterArgs);
        },
        ...
        _initViewSettingsDialog : function () {
            var oRouter = this.getRouter();
            this._oVSD = new sap.m.ViewSettingsDialog("vsd", {
                confirm: function (oEvent) {
                    var oSortItem = oEvent.getParameter("sortItem");
                    this._oRouterArgs.query.sortField = oSortItem.getKey();
                    this._oRouterArgs.query.sortDescending = oEvent.getParameter("sortDescending");
                    delete this._oRouterArgs.query.showDialog;
                    oRouter.navTo("employeeOverview",this._oRouterArgs, true /*without history*/);
                }.bind(this),
                cancel : function (oEvent){
                    delete this._oRouterArgs.query.showDialog;
                    oRouter.navTo("employeeOverview",this._oRouterArgs, true /*without history*/);
                }.bind(this)
            });
            ...
        },
        ...
    });
});

Step 15: Reuse an Existing Route

使用已经存在的导航。

修改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}"
        itemPress=".onItemPressed">
        <headerToolbar>
            ...
        </headerToolbar>
        <columns>
            ...
        </columns>
        <items>
            <ColumnListItem type="Active">
                <cells>
                    ...
                </cells>
            </ColumnListItem>
        </items>
    </Table>
</mvc:View>

为itemPress注册一个onItemPressed事件,并且将Item的type设置为Active,这样就可以对item进行点击。

修改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", {
        ...
        _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);
        },
        onItemPressed : function (oEvent) {
            var oItem, oCtx, oRouter;
            oItem = oEvent.getParameter("listItem");
            oCtx = oItem.getBindingContext();
            this.getRouter().navTo("employeeResume",{
                employeeId : oCtx.getProperty("EmployeeID"),
                query : {
                    tab : "Info"
                }
            });
        }
    });
});

在controller中添加onItemPressed函数,当item被点击时,可以触发该事件。

这样就可以导航到路由employeeResume中。

Step 16: Handle Invalid Hashes by Listening to Bypassed Events

使用Bypassed事件,来监听无效的hash值。

修改App.controller.js

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

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

        onInit: function () {
            // This is ONLY for being used within the tutorial.
            // The default log level of the current running environment may be higher than INFO,
            // in order to see the debug info in the console, the log level needs to be explicitly
            // set to INFO here.
            // But for application development, the log level doesn't need to be set again in the code.
            Log.setLevel(Log.Level.INFO);

            var oRouter = this.getRouter();

            oRouter.attachBypassed(function (oEvent) {
                var sHash = oEvent.getParameter("hash");
                // do something here, i.e. send logging data to the backend for analysis
                // telling what resource the user tried to access...
                Log.info("Sorry, but the hash '" + sHash + "' is invalid.", "The resource was not found.");
            });
        }

    });

});

当路由中的hash值无效时,可以触发该事件。可以用来分析为何发生这种问题。

Step 17: Listen to Matched Events of Any Route

使用attachRouteMatched函数来监听所有的路由时间,用于进行分析路由被触发的频率等信息。

修改App.controller.js

sap.ui.define([
    "sap/ui/demo/nav/controller/BaseController"
], function (BaseController) {
    "use strict";
    return BaseController.extend("sap.ui.demo.nav.controller.App", {
        onInit: function () {
            var oRouter = this.getRouter();
            oRouter.attachBypassed(function (oEvent) {
                var sHash = oEvent.getParameter("hash");
                // do something here, i.e. send logging data to the back end for analysis
                // telling what resource the user tried to access...
                jQuery.sap.log.info("Sorry, but the hash '" + sHash + "' is invalid.", "The resource was not found.");
            });
            oRouter.attachRouteMatched(function (oEvent){
                var sRouteName = oEvent.getParameter("name");
                // do something, i.e. send usage statistics to back end
                // in order to improve our app and the user experience (Build-Measure-Learn cycle)
                jQuery.sap.log.info("User accessed route " + sRouteName + ", timestamp = " + new Date().getTime());
            });
        }
    });
});

link https://sapui5.hana.ondemand.com/#/topic/1b6dcd39a6a74f528b27ddb22f15af0d

原文地址:https://www.cnblogs.com/suoluo119/p/11550155.html