上一章讲了Fiori开发的准备,以及宇宙至简之HelloWorld。
SAP学习笔记 - 开发14 - 前端Fiori开发 HelloWorld-CSDN博客
本章继续学习 Fiori 开发的知识:
Bootstrap,Controls,MVC(Model,View,Controller),Modules的概念。
目录
[3,XML View](#3,XML View)
[6,JSON Model](#6,JSON Model)
下面是详细内容。
1,Boostrap
所谓的Bootstrap,就是加载,引导。
你要用OpenUI5,那你咋用呢?你得加载UI5的包(就是一个js文件),然后才能用里面的功能。
1-1,先改/加几个文件
1),index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>UI5 Walkthrough</title>
<script
id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
data-sap-ui-theme="sap_horizon"
data-sap-ui-libs="sap.m"
data-sap-ui-compat-version="edge"
data-sap-ui-async="true"
data-sap-ui-on-init="module:ui5/walkthrough/index"
data-sap-ui-resource-roots='{
"ui5.walkthrough": "./"
}'>
</script>
</head>
<body>
<div>Hello World</div>
</body>
</html>
把上一章学习用的VSCode打开,然后把 index.html 替换成上面的内容

2),index.js
加完文件默认就给写了个框架,这个还比较好哈

先按官网写成下面这样看看效果
sap.ui.define([], () => {
"use strict";
alert("UI5 is ready");
});

然后 用 ui5 serve 启动。跑出来是这样的

然后按下 F12 键,发现咋出错了呢?
官方文档有点儿挫哈,其实这里就是它先假定你已经把SAP UI5的js给下载到本地了,咱还没下呢

或者你可以这么理解,官网上面的代码,其相对路径是基于它自己网址的,比如下面是完整路径
https://openui5.hana.ondemand.com/resources/sap-ui-core.js

我们可以下载下来,然后放到本地,作为我们自己的相对路径,
或者你直接写上面那个完整路径也OK
我这里改成完整路径:https://openui5.hana.ondemand.com/resources/sap-ui-core.js

这样再跑一下,就能加载了

1-2,简单说一下几个属性
- src="resources/sap-ui-core.js"
这个上面已经说了,就是指向UI5 js文件的路径。现实项目一般都会指向本地js文件
- data-sap-ui-theme="sap_horizon"
这个就是css样式主题
- data-sap-ui-libs="sap.m"
这个就是使用的库,sap.m 是 SAP Fiori 应用的标准移动控件库,比如button,text...
- data-sap-ui-compat-version="edge"
这个表示使用的是最新稳定版本,可能不包含向后兼容的过时版本内容
- data-sap-ui-async="true"
这个表示适用异步
- data-sap-ui-on-init="module:ui5/walkthrough/index"
这个就相当于加个包名
- data-sap-ui-resource-roots='{
"ui5.walkthrough": "./"
}'>
这个东西有点儿意思,和上面那个配套,就是该包 ui5/walkthrough 实际指向的是当前文件的所属文件夹
上面用的是sap.m库,这里再说几个常用的库:
库名 | 用途 |
---|---|
sap.m |
移动端控件 (Fiori 标准) |
sap.f |
Flexible Column Layout 等布局 |
sap.ui.table |
高级表格控件 |
sap.tnt |
工具类控件 (SideNavigation 等) |
上面写了那个data-sap-ui-libs 之后,运行的时候,浏览器会下载这么一大堆内容:
(实际项目当中,应该也会把这些拿过去放本地吧,这个我也不太确定)

2,Control(控件)
也是需要先改几个文件:
1),index.html
跟上面差不多,就是加个body 标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>UI5 Walkthrough</title>
<script
id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_horizon"
data-sap-ui-libs="sap.m"
data-sap-ui-compat-version="edge"
data-sap-ui-async="true"
data-sap-ui-on-init="module:ui5/walkthrough/index"
data-sap-ui-resource-roots='{
"ui5.walkthrough": "./"
}'>
</script>
</head>
<body class="sapUiBody" id="content">
Hello, this is body's contents.
</body>
</html>
2),index.js
这里用的是 sap/m 库下面的Text 控件
sap.ui.define([
"sap/m/Text"
], (Text) => {
"use strict";
new Text({
text: "This is sap/m/Text Control - Hello World"
}).placeAt("content");
});

跑一下看看结果
下面这个是index.html 文件里面写的文本再加上sap/m/Text组件里面 placeAt 函数加到后面的。
- Hello, this is body's contents. This is sap/m/Text Control - Hello World

3,XML View
上面显示网页内容的时候,是在index.js 里面直接用 Control,比如 new Text 这种来实现。
那要是这么用的话,实际画面一般都很复杂,不太好画。
SAP提供了XML View这种方式来方便的渲染前端。
1),App.view.xml
新建App.view.xml之后,也是生成了默认的代码:

咱们也是修改一下先:
<mvc:View
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Text text="Hello World in mvc:View"/>
</mvc:View>

视图创建好以后该怎么加载呢?就用index.js来控制加载。
2),index.js
sap.ui.define([
"sap/ui/core/mvc/XMLView"
], (XMLView) => {
"use strict";
XMLView.create({
viewName: "ui5.walkthrough.view.App"
}).then((oView) => oView.placeAt("content"));
});
说明一下这里的几行关键代码:
- "sap/ui/core/mvc/XMLView"
引入XMLView 模块
- viewName: "ui5.walkthrough.view.App"
这里就是指向 ui5.walkthrough (真实路径是在index.html 里面定义的)里面的view,
也就是 App.view.xml
- then((oView) => oView.placeAt("content"));
处理异步结果,使浏览器不会卡在这里,而是继续往下跑,等这里加载OK了再执行then里的代码

这样就加载了App.view.xml 视图了
这个视图的用途,就如其名,是为了写视图专用的
index.js 是该视图的控制器,用于控制加载哪个视图等等。

上面说了View(视图),以及控制使用哪个视图的index.js,那么视图里面的按钮等事件是怎么控制的呢?就需要Controllers(控制器)。
4,Controllers
1),App.view.xml
<mvc:View
controllerName="ui5.walkthrough.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Button
text="Say Hello"
press=".onShowHello"/>
</mvc:View>

说一下几行关键代码:
- controllerName="ui5.walkthrough.controller.App"
关联该View所对应的控制器,这里指的是 controller文件夹下的App.controller.js文件
- xmlns:mvc="sap.ui.core.mvc">
xmlns 指向的是命名空间,应该就是包名
- press=".onShowHello"/>
press 指的是按下,Web HTML里面叫click,但是移动设备也没法click,press比较贴切
.onShowHello,「.」(点号)指的是本控制器,即与view同名(比如这里是App)的控制器
2),App.controller.js
默认也是生成了大框

先修改一下成下面这样
sap.ui.define([
"sap/ui/core/mvc/Controller"
], (Controller) => {
"use strict";
return Controller.extend("ui5.walkthrough.controller.App", {
onShowHello() {
// show a native JavaScript alert
alert("Hello World in mvc/Controller");
}
});
});

说明一下几行关键代码:
- "sap/ui/core/mvc/Controller"
这个跟 include 差不多,引入基类
- ], (Controller) => {
将引入的基类作为参数传入
- Controller.extend("ui5.walkthrough.controller.App", {
继承基类,在此基础上加功能,这里就是加 onShowHello函数
贴张图展示上面的View,Controller之间的关系:等以后Model再加上,mvc就全乎了

跑一下看看,就是画面上有个Say Hello 按钮,点了之后,就出来一个Message

5,Modules
注意这个还不是mvc中的m,这里就指的是模块儿,具体介绍一个MessageToast模块儿。
我合计SAP是不是搞模块搞上瘾了。
咱们来看一下这个模块是个啥东西。
1),App.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast"
], (Controller, MessageToast) => {
"use strict";
return Controller.extend("ui5.walkthrough.controller.App", {
onShowHello() {
MessageToast.show("Hello World from Controller");
}
});
});
来说明一下几行关键代码:
- "sap/m/MessageToast"
导入MessageToast工具(这个就叫模块儿),不导入它你就用不了它,用Include/Import导进来
- ], (Controller, MessageToast) => {
这个东西本身叫回调函数,参数就是传入或者叫注入Include的模块儿
这里想说明一下异步的问题:只有当这些模块都加载完之后,前端才会开始执行回调
- MessageToast.show("Hello World from Controller");
加载完Module(模块)之后,进入到回调函数里面,就可以用导入的模块啦

效果就弹出来这么一个toast message
之前用alert 弹出来的,框框丑丑的,这种toast message比较漂亮
不管它过一阵子它自己就会自动消失,你点一下它就马上消失

6,JSON Model
上面那个Module不是mvc中的m,那mvc中的m 是啥呢?这不就来了,就是这个JSON Model。
1),App.Controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast",
"sap/ui/model/json/JSONModel"
], (Controller, MessageToast, JSONModel) => {
"use strict";
return Controller.extend("ui5.walkthrough.controller.App", {
onInit() {
// set data model on view
const oData = {
recipient : {
name : "World in oData"
}
};
const oModel = new JSONModel(oData);
this.getView().setModel(oModel);
},
onShowHello() {
MessageToast.show("Hello World from button");
}
});
});
下面来看看几行代码的含义:
-
"sap/ui/model/json/JSONModel"
-
], (Controller, MessageToast, JSONModel) => {
上面两句代码的意思是Include/Import JSONModel基类,然后将该类传入回调函数
-
下面这一段的意思是
-
定义一个名叫 recipient 的 oData变量(本质是Json字符串),正式项目里面,会从DB取值
-
然后把该变量给塞到JSONModel对象里面,赋值给oModel变量(常量)
-
用this.getView函数取得该Controller的同名View,即 App.view.xml
-
再用setModel 把 oModel变量赋值给该View
const oData = {
recipient : {
name : "World in oData"
}
};
const oModel = new JSONModel(oData);
this.getView().setModel(oModel);

2),App.view.xml
<mvc:View
controllerName="ui5.walkthrough.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Button
text="Say Hello"
press=".onShowHello"/>
<Input
value="{/recipient/name}"
description="Hello {/recipient/name} from View"
valueLiveUpdate="true"
width="60%"/>
</mvc:View>
看一下下面几句代码:
- <Input
value="{/recipient/name}" =》这句是属于简单取值,对应的是Controler里面的Jason的名值对
description="Hello {/recipient/name}" =》这句是属于复杂取值,和Hello字符串 掺杂在一起
valueLiveUpdate="true" =》value的即时更新,和Jason无关,value值变了,Des也会跟着变
width="60%"/>

跑一下看看

value值变为 Fiori World,Description 值会自动变为 Hello + Fiori World

画张图展示一下包括上面mvc 的整体Image:

以上就是本篇的全部内容。
更多SAP顾问业务知识请点击下面目录链接或东京老树根的博客主页