Fiori-step5-Controllers

这一节使用了一个按钮控件,用Controller来处理按钮的press事件。首先修改App.view.xml

  • 我们需要来指定连接这个view并且处理onShowHello事件的conroller的名字controllerName 这个view的属性这里同样使用了namespace。
  • 通过对按钮对象属性的赋值来实现按钮
  • press="onShowHello"按钮点击时会触发onShowHello事件

    如果一个view只是用来display信息的话,是不需要创建Controller的,一旦显性的指定了Controller,在view被加载后就会实例这个Controller

新建一个App.controller.js

这里有点绕,咨询了一位会js的同学大致知道这它的意思是发布了这个代码,用户访问的时候会先把基础包加载,就相当于在客户端建立了一个执行环境,用于执行编写的这些代码,定义了就相当于执行,执行页面浏览器就会执行,这个就是基础包做的事情。

  • use strict声明函数使用严格模式,加上后会自动检测代码问题,详解可以自行百度JavaScript use strict
  • Controller和对应的view使用同样的名字(如果他们关系是1:1的话)
  • event handler用前缀on
  • Controller的名字始终以 *.controller.js 结尾

JavaScript 模块定义

这里很有必要解释一下JavaScript module的定义规范了,要不然这语法看的糊里糊涂的,虽然大概能知道是什么意思,但自己写起来也只能做简单的copy

AMD

全称是Asynchronous Module Definition,即异步模块加载机制,简单说AMD是JavaScript的一个规范标准,它完整的描述了模块的定义,依赖关系,引用关系及加载机制。
作为一个规范,只需定义其语法API,而不关心其实现,AMD规范简单到只有一个API,就是define函数:

define([module-name?],[array-of-dependecy?],[module-factory-or-object]);

  • module-name: 模块标识,可以省略
  • array-of-dependecy: 所依赖的模块,可以省略
  • module-factory-or-object: 模块的具体实现或是一个JavaScript对象

从中可以看出前两个参数是可以省略的,第三个参数是模块的具体实现本身。(这时再回到上面图中看一下sap.ui.define是不是不晕了)

从AMD中的A Asynchronous 可以看出这个define具体的另一个性质:异步性。当define函数执行时,它首先会异步的去调第二个参数中的所依赖的模块,当所有模块完成加载以后,如果第三个参数是一个回调函数则执行,然后告诉系统模块可用,也就通知了自己所依赖的模块自己已经可用

WEBIDE实例:

下面是一个实例:

使用WEBIDE开发很方便的一点就是Layout Editor,如果用Layout Editor怎么做这个按钮功能呢,我们一起来做一遍:

  1. 新建一个index.html,基本架构出来
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>

head标签内加入meta``title

1
2
3
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title>MVC-VC demo</title>

加入bootstrap。注意这里是写在script括号内的,这很容易出错,别问我怎么知道的

1
2
3
4
5
6
7
8
9
10
11
<script
id = "sap-ui-bootstrap"
src = "https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"
data-sap-ui-resourceroots='{
"sap.ui.demo.wt":"./"}'
>
</script>

加入要初始化并放在<body>中xmlview实例,声明对应的viewName,这里是写在标签内的

1
2
3
4
5
6
7
<script>
sap.ui.getCore().attachInit(function(){
sap.ui.xmlview({
viewName: "sap.ui.demo.wt.view.App"
}).placeAt('content');
})
</script>

最后修改<body>标签,加入id和class
index.html全部代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title>MVC-VC demo</title>
<script
id = "sap-ui-bootstrap"
src = "https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"
data-sap-ui-resourceroots='{
"sap.ui.demo.wt":"./"}'
>
</script>
<script>
sap.ui.getCore().attachInit(function(){
sap.ui.xmlview({
viewName: "sap.ui.demo.wt.view.App"
}).placeAt('content');
})
</script>
</head>
<body class="sapUiBody" id = "content">
</body>
</html>

  1. 创建View
    有了viewName就应该创建对应的View了,新建文件夹view,新建xmlview文件App .view.xml

    敲入必要的namespace和指定对应的controller文件名

    1
    2
    3
    4
    5
    6
    7
    <mvc:View
    xmlns="sap.m"
    xmlns:mvc="sap.ui.core.mvc"
    controllerName="sap.ui.demo.wt.controller.App"
    >
    </mvc:View>
  2. 创建controller
    相对应的新建文件夹controller,新建controller js文件App .controller.js

    理一下思路,我们目的是要建一个有button的view,view上有按钮控件,controller就是为了控制view上的控件和数据,这里不涉及数据,我们就考虑控件,所以就需要在controller中写一个控制这个按钮的模块,就是按钮在被点击时的逻辑,也就是影响button的press事件。
    我们使用sap.ui.define()来定义一个module,前面我们知道了定义module需要三部分,模块名依赖模块具体实现,OK,我们依次加入,下面应该很直观了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    sap.ui.define(
    "modulename",
    ["sap/ui/core/mvc/Controller"],
    function(Controller){
    "use strict";
    return Controller.extend(
    "sap.ui.demo.wt.controller.App",
    {
    }
    );
    }
    );

然后加入我们最终要实现的function的内容,我们想定义一个onPress事件,用户点击时执行功能alert:

1
2
3
onPress: function(){
alert("you clicked me");
}

App.controller.js全部代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sap.ui.define(
"modulename",
["sap/ui/core/mvc/Controller"],
function(Controller){
"use strict";
return Controller.extend(
"sap.ui.demo.wt.controller.App",
{
onPress: function(){
alert("you clicked me");
}
}
);
}
);

  1. 回头编辑View
    这里我们用Layout Editor

    拖一个按钮进来:

    这里就可以通过修改控件的属性来达到想到的效果,比如这里分别改的按钮的宽度,文本,文本前加了图标,加了激活后的图标,就是点击后的图标

    然后最关键的一眇就是关联事件,点击Events,在press那里找到我们刚在controller写的onPress


    如果你点击后面的go to code按钮,会自动导航到controller文件中对应的代码位置,非常方便有木有

    你想新建事件一个也没问题,press那里选new function:

    确定后点go to code:很爽是吧

    只需要关注要实现的功能就好,这里我加一个新的alert消息

    代码有点乱,点这个,自动美颜

    这里回头看一下view的代码,Layout Editor根据我们的设置自动生成了对应的代码
    1
    2
    3
    <mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" controllerName="sap.ui.demo.wt.controller.App">
    <Button text="Click Me!" width="120px" id="__button1" activeIcon="sap-icon://accept" icon="sap-icon://activate" press="onPress1"/>
    </mvc:View>

保存执行:

HTML xmlns 属性

xmlns 属性可以在文档中定义一个或多个可供选择的命名空间。该属性可以放置在文档内任何元素的开始标签中。该属性的值类似于 URL,它定义了一个命名空间,浏览器会将此命名空间用于该属性所在元素内的所有内容。

如果需要在一个 div 元素中显示一串数学公式,则可以为该 div 元素定义一个数学命名空间。比如这样:

1
<div html xmlns="http://www.w3.org/1999/Math/MathMl">x3/x</div>

如果您不希望在每次显示除法公式时都在 div 元素中定义 xmlns 属性,那么更好的办法是在文档的开头处定义具有前缀的命名空间:

1
2
<html xmlns="http://www.w3.org/1999/xhtml">
xmlns:math="http://www.w3.org/1999/Math/MathMl">

然后,您就可以在 div 中使用该前缀了,就像这样:

1
<math:div>x3/X<div>

Jim Guo wechat
ex. subscribe to my blog by scanning my public wechat account