Welcome to Jim's Blog

欢迎欢迎


  • 首页

  • 分类

  • 归档

  • 标签

  • 搜索

Fiori-MVC

发表于 2017-08-10 | 分类于 Fiori | | 阅读次数

很有必要把MVC单独拿出来认真的讨论一次。

MVC的好处我们就不多谈了,百度很多,但在SAPGUI中是如何做的呢?

简单来说

  • Model: 专门管理application中的数据
  • View: 定义和渲染UI
  • Controller: 对View Event进行反应和在用户对View和Model修改进行交互时进行反应
关系

View和Controller的关系一般是1:1,但也允许多个Controller控件一个View,他们叫们应用控件器。当然View也可没有对应的Controller。一般1个View可以有或继承一个SAPUI5 Model。

Model

数据绑定

Model One-way Two-way One-time
Resource model – – X
JSON model X X X
XML model X X X
OData model X X X
Model Default binding mode
Resource model One-time
JSON model Two-way
XML model Two-way
OData model One-way

一般来说, MVC中的Model主要是用来hold数据并且提供方法去访问和更新数据库中的数据。
SAPUI5提供了以下几种预定义的Model:

  • OData Model
    OData Model支持多种绑定模式:双向(默认)绑定,意向绑定,一定性绑定。但需要注意的是双向绑定只支持属性值,不能对aggregations。OData Model现在有两个版本:OData V2和OData V4。
  • JSON Model
    JSON Model可以用来绑定控件到序列化的JavaScript对象数据上,它是客户端上的一种Model,所以当数据量不是在太大,完全可以保存在客户端时就可以选择使用JSON Model。它支持双向(默认)绑定、单向绑定和一次性绑定。
  • XML Model
    使用上基本上和JSON Model一致的,适用少量数据。
  • Resource Model
    这个主要是用来处理多语言的数据,比如保存多个语言的提示消息和文本信息,因为它只处理静态文本,所以这个只支持一次性绑定。

就是下面这张图,除了OData Model,其它三种都是做在客户端的,不需要访问server就可以使用。OData Model是服务器端的Model,需要UI通过请求从server取数。除这些之外还可以开发自定义的Model。

OData V2 Model

OData Model 是服务器端的Model,意味着数据集只在server端有效,数据的操作,比如排序和过滤都是在server来完成,client只有发送请求得到数据。

发往后端数据请求的发起可以由list binding(ODataListBinding),element binding(ODataContextBinding)和 OData Model的CRUD function来触发。 Property binding(ODataPropertyBinding)不能触发请求。

OData Model现在支持OData version 2.0,相比1.0以下面几个特性:

  1. 默认是JSON 格式
  2. 双向绑定只支持Property change,还不支持aggregations
  3. 默认为单向绑定
  4. 可以在client端进行排序和数据过滤
  5. 所有的请求都支持Bundle
  6. 所有的数据可以被cached in Model
  7. 支持message handling
创建Model实例

1 个Model实例只能负责 1 个OData服务,如果要访问多个服务,就必须要创建多个实例。创建OData Model实例必须有的一个参数就是服务的URL。第一个参数

1
2
var oModel = new sap.ui.model.odata.v2.ODataModel("http://services.odata.org/Northwind/Northwind.svc/");
var oModel = new sap.ui.model.odata.v2.ODataModel({serviceUrl: "http://services.odata.org/Northwind/Northwind.svc"});

每当创建一个ODataModel时就会发送一个metadata的服务请求,如果多个ODataModel使用同一个服务的话,仅第一个实例触发metadata请求。

1
http://services.odata.org/Northwind/Northwind.svc/$metadata

实例的getServiceMetadata()方法可以查看JSON格式的metadata

1
var oMetadata = oModel.getServiceMetadata();

可以增加附加参数来配置OData services,SAPUI5会根据相应的绑定方式自动设定一些参数,ODataModel现在支持$select和$expend,可以有不同的方式来增加这些附件参数:

  • 直接在URL后加:

    1
    var oModel = new sap.ui.model.odata.v2.ODataModel("http://myserver/MyService.svc/?myParam=value&myParam2=value");
  • 用mparameters map传递给URL(也可以只传入一个):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var oModel = new sap.ui.model.odata.v2.ODataModel({
    serviceUrl: "http://services.odata.org/Northwind/Northwind.svc",
    serviceUrlParams: {
    myParam: "value1",
    myParam2: "value2"
    },
    metadataUrlParams: {
    myParam: "value1",
    myParam2: "value2"
    }
    });

除了serviceUrl和serviceUrlParams之外,还有headers可以指定HTTP的headers:

1
2
3
4
5
6
var oModel = new sap.ui.model.odata.v2.ODataModel({
headers: {
"myHeader1" : "value1",
"myHeader2" : "value2"
}
});

1
oModel.setHeaders({"myHeader1" : "value1", "myHeader2" : "value2"});

注意当指定HTTP header参数时原有的参数会被覆盖,有些内部的参数是改不了的,如:

1
2
3
4
5
"accept"
"accept-language"
"maxdataserviceversion"
"dataserviceversion"
"x-csrf-token"

寻址Entities:绑定语法

ODataModel的路径绑定语法和相对于在OData中用于访问特定Entity或EntitySet服务URL的URL路径相匹配。
根据服务metadata中定义的OData服务的结构,您可以访问OData模型提供的数据。URL参数,例如过滤器,是不能添加到绑定路径中的。绑定路径可以是绝对路径,也可以是相对路径。绝对绑定路径立即被解析。 相对路径只有在能被转换成绝对路径的时候才可用。例如,如果一个Property绑定了一个相对路径而它的父控件绑定了一个绝对路径,那这个相对路径就可以解析成一个绝对路径。

The following binding samples within the ODataModel are taken from the Northwind demo service.

绝对路径:

1
2
"/Customers"
"/Customers('ALFKI')/Address"

相对路径如果有一个context的话就可能被解析成绝对路径,比如有一个绝对路径/Customer('ALFKI'),那么下面的相对路径

1
2
3
"CompanyName"
"Address"
"Orders"

就可以被转换成下面的绝对路径:

1
2
3
"/Customer('ALFKI')/CompanyName"
"/Customer('ALFKI')/Address"
"/Customer('ALFKI')/Orders"

Navigation properties可以被用来视别一个Entity或是多个Entities

1
2
"/Customers('ALFKI')/Orders"
"/Products(1)/Supplier"

访问OData Model的数据

从一个OData服务请求的数据会被cathed到OData Model,可以使用getData()和getProperty()方法访问,分别返回ODataModel的Entity对象和值。这些方法并不是从后台Server访问数据,所以你只能从那些请求过数据的Model中取。

1
2
oModel.getData("/Customer('ALFKI')");
oModel.getProperty("/Customer('ALFKI')/Address");

另外,这些方法只能访问单一的Entity和Property,如果要访问EntitySet的数据,需要通过List binding,这样就可以得到这些Entities的Binding context。

不要手工去修改Model内的对象或数据,一定要使用SAP提供的API来操作,或是用双向绑定的控件来修改数据。

创建Entities
为指定的EntitySet创建Entity,用createEntry()方法,方法返回一个context对象指定新创建的Entity,application可以通过双向绑定的方式对它的值进行修改,保存数据需要用到submitChanges(),回滚的话用deleteCreatedEntry()。

application可以选择在创建的对象中包含哪些属性,并且可以为这些属性传递自己的默认值,默认情况下,所有的属性值都是空的,未定义的。

EntitySet和传递的属性值必须在OData服务的metadata中存在

1
2
3
4
5
6
7
8
// create an entry of the Products collection with the specified properties and values
var oContext = oModel.createEntry("/Products", { properties: { ID:99, Name:"Product", Description:"new Product", ReleaseDate:new Date(), Price:"10.1", Rating:1} });
// binding against this entity
oForm.setBindingContext(oContext);
// submit the changes (creates entity at the backend)
oModel.submitChanges({success: mySuccessHandler, error: myErrorHandler});
// delete the created entity
oModel.deleteCreatedEntry(oContext);

如果已经提交了创建的Entity,那么Context将通过创建请求返回的路径进行更新,并将新数据导入到模型中,这样Context仍然有效,并指向新创建的Entity。

CRUD Operations
OData service是可以手工进行CRUD(Create,Read,Update,Delete)的,如果手工操作有返回值 ,数据会被Import到这个ODataModel的Cathe中,所有操作都需要一个强制性的sPath参数以及一个可选的mParameters map,Create和Update操作还需要另一个强制的参数oData来传递要创建或修改的对象,每个操作返回一个包含一个函数中止的对象,这个对象可以用来中止请求。如果请求被中止,将调用错误处理程序。这将确保为每个请求执行成功或错误处理程序。还可以传递附加的头数据、URL参数或eTag。

  • Creating entities
    create函数触发一个OData服务的POST请求,该服务是在创建OData模型时指定的。应用程序必须指定EntitySet,其中将创建新的Entity和Entity数据。

    1
    2
    3
    4
    5
    var oData = {
    ProductId: 999,
    ProductName: "myProduct"
    }
    oModel.create("/Products", oData, {success: mySuccessHandler, error: myErrorHandler});
  • Reading entities
    read函数触发一个GET请求到指定的路径。在创建OData模型时,将从OData服务中检索路径。检索到的数据在成功回调处理程序函数中返回。

    1
    oModel.read("/Products(999)", {success: mySuccessHandler, error: myErrorHandler});
  • Updating entities
    update函数会触发一个对OData服务的put/merge请求,该服务是在OData模型创建时指定的。在成功请求更新模型中的绑定之后,刷新会自动触发。

    1
    2
    3
    4
    5
    var oData = {
    ProductId: 999,
    ProductName: "myProductUpdated"
    }
    oModel.update("/Products(999)", oData, {success: mySuccessHandler, error: myErrorHandler});
  • Deleting entities
    remove函数触发对OData服务的删除请求,该服务是在创建OData模型时指定的。应用程序必须指定要删除的条目的路径。

    1
    oModel.remove("/Products(999)", {success: mySuccessHandler, error: myErrorHandler});
  • Refresh after change
    该模型提供了一种机制来自动刷新依赖于发生更改的Entity的绑定。如果您执行一个创建、更新或删除功能,该模型将识别绑定并触发这些绑定的刷新。如果模型以批处理模式运行,则刷新请求与相同批处理请求中的更改捆绑在一起。您可以通过调用setRefreshAfterChange(false)禁用自动刷新。如果自动刷新被禁用,应用程序必须处理刷新各自的绑定。

    1
    oModel.setRefreshAfterChange(false);

并发控制、ETags
OData使用HTTP ETags来实现优化并发控制。必须配置服务才能提供这些服务。每个CRUD请求的参数映射中都可以传递ETag。如果没有传递ETag,则使用缓存实体的ETag,前提是已经加载了Cach。
XSRF Token
为了解决跨站点请求的伪造,OData服务可能需要XSRF令牌来满足客户端应用程序的更改请求。在这种情况下,客户端必须从服务器获取一个令牌,并将每个更改请求发送到服务器。在读取元数据时,OData模型会获取XSRF标记,然后自动将其发送给每个写请求头。如果令牌不再有效,则可以通过调用OData模型中的refreshSecurityToken函数来获取新的令牌。令牌以对服务文档的请求来获取。为了确保获得有效的令牌,请确保服务文档没有被缓存。
Refreshing the Model
刷新函数刷新了一个OData模型中的所有数据。每个绑定从服务器重新加载它的数据。对于列表或元素绑定,将触发对后端的一个新请求。如果XSRF令牌不再有效,则必须使用对服务文档的read请求再次获取它。通过手动CRUD请求导入的数据不会自动重新加载。
Batch Processing
v2.ODataModel 支持两种方式的batch处理:

  • 默认:一个线程中的所有请求都被收集并打包在一个batch批处理请求中,这意味着在当前调用堆栈完成后立即将请求发送到超时。这包括所有的手动CRUD请求以及绑定所触发的请求。
  • 延迟:

使用MVC,sapui5如何确定view和controller的文件的名称和位置呢? 有以下三种方法来声明文件的位置:

  1. sap.ui.localResources()
  2. jQuery.sap.registerModulePath()
  3. bootstrap声明: data-sap-ui-resourceroots=’{“name”: “”}’

sap.ui.localResources()

sap.ui.localResources()语法:

1
sap.ui.localResources(sModuleNamePrefix);

将sModuleNamePrefix注册为html文件(比如index.html作为当前文件夹)下sModuleNamePrefix子文件夹。如果sModuleNamePrefix中含有点号,所有的点被替换成/。比如,view name为master,如果sap.ui.localResources("myapp.viewsforbutton");,则sapui在./myapp/viewforbutton文件夹下查找view文件的代码。文件的扩展名由view的类型决定。

jQuery.sap.registerModulePath()

jQuery.sap.registerModulePath()的语法:

1
jQuery.sap.registerModulePath(sModuleNamePrefix, sURL);

把sModuleNamePrefix注册为sURL,比如:jQuery.sap.registerModulePath("mainview", "./mainview/");把mainview注册为当前文件夹下的mainview文件夹。
这种方法能实现sap.ul.localResources()相同的功能,但更加灵活。

bootstrap申明resourcesroots

下面的声明实现上述同样功能。

1
2
3
4
5
6
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-resourceroots='{"mainview" : "./mainview/"}'>
</script>

Model的绑定

一个Model可以被set到core,component controller,view,controls(Aggregation),controls(element),controls(property)不同的level。所有controls和views都会集成父级的model。

注意: Fiori App不要set model到UI core,应该set到对应的view或是component controller。

控件和model需要通过路径绑定进行显示,有以下几种绑定类型:

  1. Property binding
  2. Element binding
  3. Aggregation binding

Aggregation and Expression Binding

Aggregation Binding用于绑定一个多行数据的数据集到一个UI控件上,比如tables,lists或pulldown。语法:bindAggregation(sPath,oTemplate)

Expression Binding可以用表达式来替代custom formatter functions。只要用在一些细微的控制。比如判断字段的visible属性,下面是一个对比的例子:

参考

http://blog.csdn.net/stone0823/article/details/53955928

temp

发表于 2017-08-04 | | 阅读次数

不同的设备怎么判断?
在component.js中引用类“sap/ui/device”,然后声明一个全局model:

1
this.setModel(models.createDeviceModel(),"device");

然后在各个view中就可以用device这个model来进行判断

运算符:

在html中可以直接使用$来进行简单的运算,如根据一个字段的值控件另一个字段的属性:
visible="{=${/status} === 'critical' &amp;&amp; ${/orderAmount} > 1000}"
这个例子就是用status是否等于critical并且orderAmount大于1000两个条件来决定visible是true还是false。这里用的是两个条件,&amp;&amp; (其实就是&&,因为&是特殊符号,直接写会报错)就是“与运算”。“或运算”的写法是||。
这里也可以用三目运算,如:
"{=${/orderAmount}>1000 ? ${i18n/high}:${i18n/normal}}"判断orderAmount是否大于1000,是就显示{i18n/high},否则就显示{i18n/normal}

Formatter
  1. 标准的formatter

    常用的标准format可以在sap/ui/core/format中查找,如日期时间:sap/ui/core/format/DateFormat,
  2. 自定义formatter

Fiori-Tcode

发表于 2017-08-03 | 分类于 Fiori | | 阅读次数

Fiori中一些有用的TCODE:

TCODE Description
SEGW SAP Gateway Service Builder
SMICM ICF Monitor
PFCG Role Maintenance
LPD_CUST Launchpad Customizing
SICF HTTP Service Hierarchy Maintenance
/IWFND/ERROR_LOG SAP Gateway Error Log
/IWFND/MAINT_SERVICE Active and Maintain Services
/IWFND/GW_CLIENT SAP Gateway client
/IWFND/VIRUS_SCAN Configuration of SAP GW Virus Scan
VSCANPROFILE Configuration of Virus Scan Profile
/UI5/THEME_TOOL UI Theme Tool
/UI5/THEME_DESIGNER UI Theme Designer
/UI2/CACHE Register service for UI2 cache use
/UI2/CACHE_DEL Delete cache entries
/UI2/CHIP Chip Registration
/UI2/CUST Customizing of UI Technologies
/UI2/FLC Fiori Launchpad Checks
/UI2/FLIA Fiori Launchpad Intent Analyis
/UI2/FLP SAP Fiori Launchpad
/UI2/FLP_CONTCHECK Fiori Launchpad – Content Checks
/UI2/FLP_INTENTCHECK Fiori Launchpad – Intent Checks
/UI2/FLPD_CONF Fiori Launchpad?Designer (cross-client)
/UI2/FLPD_CUST Fiori Launchpad?Designer (client-specific)
/UI2/GW_ACTIVATE Gateway – Activation
/UI2/GW_APPS_LOG Gateway – Application Log
/UI2/GW_ERR_LOG Gateway – Error Log
/UI2/GW_MAINT_SRV Gateway – Service Maintenance
/UI2/GW_SYS_ALIAS Gateway – Manage SAP System Alias
/UI2/NAV Register navigation objects
/UI2/NAVPROV Define navigation provider
/UI2/NWBC Start UI2 NWBC
/UI2/NWBC_CFG_CUST NWBC Configuration (Customer)
/UI2/NWBC_CFG_P_CUST NWBC Config: Define Parameter (Cust)
/UI2/NWBC_CFG_P_SAP NWBC Config: Define Parameter (SAP)
/UI2/NWBC_CFG_SAP NWBC Configuration (SAP)
/UI2/PERS_DEL Cleanup Personalisatation Service
/UI2/POWL Register POWL for OData consumption
/UI2/SEMOBJ Define Semantic Object – Customer
/UI2/SEMOBJ_SAP Define Semantic Object – SAP

Fiori-Gateway

发表于 2017-08-03 | 分类于 Fiori | | 阅读次数

0 Prerequisites

  1. 附件安装
    NetWeaver 7.0, 7.01, 7.02 or 7.31需要安装3个附件 IW_BEP, GW_CORE,IW_FND,7.4以后可以合成了一个SAP_GWFND
    TCODE:SAINT
  2. 参数设置(TCODE:RZ10)
    login/accept_sso2_ticket = 1

    login/create_sso2_ticket = 2

    没有这两个设置启动Gateway时会有问题,参考SSO problem with the SAP Gateway Client /IWFND/GW_CLIENT

    1 激活Gateway

    2 创建别名


    这里不同的部署方式会略有不同,具体参考online help

    3种部署方式:

    Central Hub Deployment (service development in the SAP Business Suite backend system)

    Central Hub Deployment (service development in SAP Gateway hub system)

    Embedded Deployment (service development in the SAP Business Suite system)

具体可以参考:https://help.sap.com/saphelp_nw74/helpdata/en/c5/dc22512c312314e10000000a44176d/frameset.htm
下面是一个例子:

注意System ID一定要填

3 创建一个Gateway别名




这里创建完以后在SEGW中创建的project的Service Maintenance中就可以出现了

4 激活node ’opu’






5 测试服务

参考

Quick Starter Configuration Guide – SAP Gateway
https://blogs.sap.com/2013/05/14/quick-starter-configuration-guide-sap-gateway/

https://help.sap.com/saphelp_nw74/helpdata/en/c5/dc22512c312314e10000000a44176d/frameset.htm

Fiori-Step15-18

发表于 2017-07-31 | 分类于 Fiori walkthrough | | 阅读次数


可以看出来这里将App View的控件单独拿到了一个View中
然后新建了HelloPanel.view.xml和相应的controller文件HelloPanel.controller.js
再来看一下现在的文件结构:

controller文件和View文件始终是成对出现的,data model来自component或是manifest指定的i18n,Resource来自manifest指定的css。

1…345…8
Jim Guo

Jim Guo

Hi~

36 日志
5 分类
22 标签
© 2018 Jim Guo
由 Hexo 强力驱动
主题 - NexT.Mist