SAPUI5 (24)

来源:互联网 发布:阿里云学生优惠 编辑:程序博客网 时间:2024/04/28 21:17

CRUD是应用程序的核心。openui5是一个前端的UI库,CRUD是通过oData的服务来完成。openui5提交基于http协议的请求给服务器,其它交给服务器端处理。oData协议是微软公司发起,比web service更轻量级的通讯协议。SAP的Neweaver Gateway 就是SAP以OData形式暴露后端业务数据的一个组件。SAPUI5提供的方便的数据绑定功能,将前端展示组件绑定到后端暴露的OData服务上。

使用mock server实现数据查询

目前,我们先使用mock server来模拟服务器端的功能。本次将之前的master-detail程序修改为使用GET请求获取数据并展示。在前一篇起始框架代码的基础上,做如下变更:

  1. 创建master view和master controller
  2. 创建detail view和detail controller
  3. 修改manifest.json, 将空字符串的target设为master

项目文件结构:

创建master view和master controller

Master.view.xml:

<core:View xmlns:core="sap.ui.core"            xmlns:mvc="sap.ui.core.mvc"            xmlns="sap.m"            controllerName="stonewang.sapui5.demo.controller.Master"             xmlns:html="http://www.w3.org/1999/xhtml">    <Page id="page" title="{i18n>masterViewTitle}">        <content>            <Table id="table" width="auto"                class="sapUiResponsiveMargin"                items="{/}"                noDataText="{i18n>tableNoDataText}"                growing="true"                growingScrollToLoad="true">                <headerToolbar>                    <Toolbar>                        <Title id="tableHeader" text="Suppliers List"/>                        <ToolbarSpacer />                    </Toolbar>                </headerToolbar>                <columns>                    <Column id="nameColumn"><header>                        <Text text="{i18n>tableIDColumnTitle}" id="IDColumnTitle"/></header>                    </Column>                    <Column id="unitNumberColumn"><header>                        <Text text="{i18n>tableNameColumnTitle}" id="nameColumnTitle"/></header>                    </Column>                </columns>                <items>                    <ColumnListItem                        type="Navigation" press="onItemPress">                        <cells>                            <ObjectIdentifier text="{id}"/>                            <ObjectIdentifier text="{Name}"/>                        </cells>                    </ColumnListItem>                </items>            </Table>        </content>      </Page></core:View>

重点说明:

  • 因为Component.js文件中:
var oAppModel = new sap.ui.model.json.JSONModel("/Suppliers");

直接将路径设为/Suppliers,所以上面代码中,master viewsap.m.Tableitems属性设置为{/},是相对于/Suppliers的。这将导致后面我们在表达model中数据的路径时,和之前不同。

Master.controller.js:

sap.ui.define([        "sap/ui/core/mvc/Controller",        "sap/ui/core/UIComponent"    ],          function(Controller, UIComponent){       "use strict";        return Controller.extend("stonewang.sapui5.demo.controller.Master", {            onItemPress: function(oEvent){                var oRouter = UIComponent.getRouterFor(this);                var oItem = oEvent.getSource();                var sPath = oItem.getBindingContext().getPath();                oRouter.navTo("detail", {                     supplierPath: encodeURIComponent(sPath)                }, true);             }         });    });

和之前的代码相比,没有变化。

创建detail view和detail controller

Detail.view.xml:

<core:View xmlns:core="sap.ui.core"            xmlns:mvc="sap.ui.core.mvc"            xmlns="sap.m"            controllerName="stonewang.sapui5.demo.controller.Detail"             xmlns:html="http://www.w3.org/1999/xhtml">    <Page id="page" showNavButton="true" navButtonPress="onNavPress"          title="{i18n>detailTitle}">        <content>            <ObjectHeader title="{Name}" number="ID: {id}">                <ObjectAttribute text="{Address/Street}, {Address/City}"/>            </ObjectHeader>        </content>    </Page></core:View>

Detail.controller.js:

sap.ui.define([        "sap/ui/core/mvc/Controller",        "sap/ui/core/UIComponent",        "sap/ui/core/routing/History"    ],          function(Controller, UIComponent, History){       "use strict";        return Controller.extend("stonewang.sapui5.demo.controller.Detail", {            // add functions here            onInit: function(){                var oRouter = UIComponent.getRouterFor(this);                oRouter.getRoute("detail")                    .attachPatternMatched(this._onObjectMatched, this);             },            onNavPress: function() {                var oHistory = History.getInstance();                var sPreviousHash = oHistory.getPreviousHash();                if (sPreviousHash != undefined){                    window.history.go(-1);                }else{                    var oRouter = UIComponent.getRouterFor(this);                    oRouter.navTo("master",{}, true);                }            },            _onObjectMatched: function (oEvent) {                           var sPath = oEvent.getParameter("arguments").supplierPath;                console.log(decodeURIComponent(sPath));                this.getView().bindElement({path: decodeURIComponent(sPath)});            }         });        });

修改manifest.json, 将空字符串的target设为master

修改target,并增加master和detail所映射的view:

"sap.ui5": {        ...            "routes": [                {                    "pattern": "",                    "name": "master",                    "target": "master"                },                {                    "pattern": "detail/{supplierPath}",                    "name": "detail",                    "target": "detail"                }            ],            "targets": {                "master": {                    "viewName": "Master",                    "viewLevel": 1                },                "detail": {                    "viewName": "Detail",                    "viewLevel": 2                },                "notFound": {                    "viewName": "NotFound",                    "viewId": "notFound"                }            }        }

使用view model

现在我们要在detail view中增加两个按钮,用于直接在页面中导航到上一条和下一条数据。界面如下:

同时,这两个按钮根据当前所在行,enabled属性动态变化,比如当处在第一行,向上就为灰色。view model适合这种动态设定UI元素的状态。方法:

1) 实例化view model

Detail.controller.js文件的onInit事件处理器中实例化view model:

// 创建一个model view, 包含两个button是否enabled的布尔值var oViewModel = new sap.ui.model.json.JSONModel({    canGoPrev: false,    canGoNext: false});this.getView().setModel(oViewModel, "viewModel");

2) Detail view中增加按钮

Detail.view.xml文件中增加两个按钮,设置enabled属性:

<subHeader>    <Toolbar>        <ToolbarSpacer />        <Button icon="sap-icon://slim-arrow-up"                         press="onPageUp"                         enabled="{viewModel>/canGoPrev}" />        <Button icon="sap-icon://slim-arrow-down"                         press="onPageDown"                         enabled="{viewModel>/canGoNext}" />    </Toolbar>      </subHeader>

3) 在detail controller中增加更新状态的代码

Detail.controller.js文件中的_onObjectMatched函数中,定义sObjectID:

this.sObjectID = sPath.substr(sPath.lastIndexOf("/")+1);

因为router的导航是基于路径的,这种方法可以获取最后一个/之后的数字,可以用于知道当前数据所在位置。
比如当处于第一条数据,sObjectID=0,当处于第二条数据,sObjectID=1。

然后再添加一个方法_updateViewModel

_updateViewModel: function(oEvent){    var oModel = this.getView().getModel();    var that = this;    var oViewModel = that.getView().getModel("viewModel");      var nextObjId = parseInt(that.sObjectID) + 1;    var prevObjId = parseInt(that.sObjectID) - 1;                       var bNextEnable = !!oModel.getProperty("/" + nextObjId);    var bPrevEnable = !!oModel.getProperty("/" + prevObjId);    oViewModel.setProperty("/canGoNext", bNextEnable);    oViewModel.setProperty("/canGoPrev", bPrevEnable);    } });

代码说明:

  • sObjectId转换成number,加1,使用oModel.getProperty("/" + nextObjId)看看是否存在下一条记录。如果不存在,则表达式为undefinedvar bNextEnable = !!oModel.getProperty("/" + nextObjId);将表达式转换成与之对应的boolean类型。比如表达式为undefined,则!exp为true,!!exp为false

  • 根据这两个值,利用JSONModel.setProperty设置view model的canGoNextcanGoPrev

  • _updateViewModel函数完成,在_onObjectMatched添加调用的语句,_onObjectMatched函数的完整代码如下:

_onObjectMatched: function (oEvent) {           // 数据绑定    var sPath         = decodeURIComponent(oEvent.getParameter("arguments").supplierPath);    this.getView().bindElement({path: sPath});                  this.sObjectID = sPath.substr(sPath.lastIndexOf("/")+1);    this._updateViewModel();}

4) 添加onPageUp和onPageDown处理代码

onPageUp: function(oEvent){                 var sId = parseInt(this.sObjectID);    sId = sId - 1;    var oRouter = UIComponent.getRouterFor(this);    var sNewRoute = encodeURIComponent("/"+sId);    oRouter.navTo("detail", {supplierPath: sNewRoute});},onPageDown: function(oEvent){    var sId = parseInt(this.sObjectID);    sId = sId + 1;    var oRouter = UIComponent.getRouterFor(this);                   var sNewRoute = encodeURIComponent("/"+sId);    oRouter.navTo("detail", {supplierPath: sNewRoute});},

切换到其它数据,也是利用routernavTo方法。

源码:

24_zui5_crud_retrieve_v1

24_zui5_crud_retrieve_v2

0 0
原创粉丝点击