MVC 是一种架构模式,SAPUI5 对 MVC 提供了良好的支持。
什么是 MVC?
MVC 是 Model、View、Controller 的简称,用于将程序的数据、界面展示和用户交互分离,通过这种分离,可以简化开发,以及让某部分变动的时候,不需要影响其他部分,从而降低耦合。
Model: 模型 - 代表应用程序的数据
View: 通过界面展示应用程序的数据和其它界面元素
Controller: 处理应用程序的数据,以及处理用户的交互。
下面的图示来自 SAPUI5 Tutorial,清晰地说明了三个概念之间的关系:
图片来自SAPUI5 Tutorial
Model 和 View 之间的关系:OpenUI5 有单向绑定或者双向绑定两种绑定模式,通过绑定,当 model 变更时, UI 自动更新。
Controller 和 View 之间的关系:View 通知 Controller,或者 Controller使用 API 来修改 View。
Controller 和 Model 的关系:Model 通知 Controller,或者 Controller 修改 Model
我们用一个实例来演示 MVC 。我们要实现的一个非常简单的功能:在页面上放一个 Button,当用户点击的时候,显示 “Hlello”。对,前面 Hello World 程序已经实现过。我们先不用 MVC 的方式来实现,为了有一点新的东西在代码里面,我们将 JavaScript 的 Alert 替换成sap.m.MessageBox,OpenUI5 风格的对话框。
sap.m.MessageBox 对象
sap.m.MessageBox 是 OpenUI5 提供的对话框,可以显示信息、警告、错误等等。MessageBox 类是静态类,在使用之前必须执行jQuery.sap.require(“sap.m.MessageBox”);语句。OpenUI5 包含 jQuery 包,jQuery.sap.require(vModuleName) 方法的作用是加载指定的模块并且执行,这样 MessageBox 的 show() 方法才能运行。
sap.m.MessageBox 提供如下显示对话框的方法:
sap.m.MessageBox.alert(vMessage, mOptions*?*) 对话框显示消息,有一个OK按钮(注意在中文环境中翻译为“确定”),没有图标(icon);
sap.m.MessageBox.confirm(vMessage, mOptions*?*) 确认对话框,询问是否确定,有一个OK按钮和Cancel按钮,一个问号的图标。
sap.m.MessageBox.error(vMessage, mOptions*?*) 显示错误对话框,带有错误图标和关闭按钮Displays an error dialog with the given message, an ERROR icon, a CLOSE button.
sap.m.MessageBox.information(vMessage, mOptions*?*) 消息对话框,带有INFO图标和OK按钮。
sap.m.MessageBox.show(vMessage, mOptions*?*) 显示对话框,类型为sap.m.DialogType.Message,图标和按钮由开发人员自行定义,相对灵活一些。
sap.m.MessageBox.success(vMessage, mOptions*?*) 显示成功对话框,带有SUCCESS图标和OK按钮。
sap.m.MessageBox.warning(vMessage, mOptions*?*) 显示警告消息,带有WARNING图标和OK按钮。
SAPUI5 有哪些类型的 View?
SAPUI5 提供了JSView, XMLView, JSONView 和HTMLView 等几种类型。SAPUI5 的示例代码主要采用 XMLView,这个也是现代开发语言的趋势。而对开发人员来说,JSView 也可能感觉比较舒适,所以建议重点掌握这两个类型就可以了,并且学会在两种风格的代码之间进行翻译。
新建一个 SAPUI5 Application Project,project name 为zsapui5_butto_mvc,勾选 Create an Initial View:
点击 Next,选择 JavaScript View,把 View 命名为 master:
点击 Finish,代码框架创建完成。来探索一下代码:
代码说明
index.html 文件
首先还是 index.html (在 WebContent 文件夹下),我们注意到,Application area 的代码发生了变化,这个是另一个常用的模式。
<script>
sap.ui.localResources("zsapui5_button_mvc");
var app = new sap.m.App({initialPage:"idmaster1"});
var page = sap.ui.view({
id:"idmaster1",
viewName:"zsapui5_button_mvc.master",
type:sap.ui.core.mvc.ViewType.JS});
app.addPage(page);
app.placeAt("content");
</script
sap.ui.localResources(“zsapui5_button_mvc”); : 作用是将当前目录下的 zsapui5_button_mvc 文件夹注册为当前文件夹,程序会在这个文件夹下查找 view 的代码和 controller 的代码。我们刚才把 view 命名为 master,所以 OpenUI5 在 ./zsapui5_button_mvc 文件夹下查找master.view.js,把这个文件作为存放 view 的代码文件。同理,在这个文件夹下查找 master.controller.js,把这个文件作为存放 controller 的代码文件。后面我们会专门介绍文件位置如何处理的问题,暂且不表。
new sap.m.App: 创建一个 sap.m.App 对象,sap.m.App 对象是
SAP 移动 app 的根元素 (root element),它提供导航的功能,并且将一些
header 标签加到 HTML 页,这些 header 标签对移动 app 有某些作用。
sap.ui.view: 定义一个 view,设定 id, view name 和 type,这个 view
赋值给 page 并添加到 app 中。app 的初始页需要用到 view 的 id,而view 的 name 则和上面 sap.ui.localResources(“zsapui5_button_mvc”);
语句一起,确定了代码文件的位置。
app.placeAt(“content”): app 放在 DIV 中,UI 就可以显示。
View 文件
View 文件为 WebContent/zsapui5_button_mvc/master.view.js。代码如下:
sap.ui.jsview("zsapui5_button_mvc.master", {
/** Specifies the Controller belonging to this View.
* In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
* @memberOf zsapui5_button_mvc.master
*/
getControllerName : function() {
return "zsapui5_button_mvc.master";
},
/** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed.
* Since the Controller is given to this method, its event handlers can be attached right away.
* @memberOf zsapui5_button_mvc.master
*/
createContent : function(oController) {
return new sap.m.Page({
title: "Title",
content: [
]
});
}
});
里面有两个函数,getControllerName 函数用于返回 controller name,createContent 函数用于返回页面上要显示的元素,比如我们现在要返回的是一个 Button,我们将这个函数改写为:
createContent : function(oController) {
var oButton = new sap.m.Button({
text: "Click me",
press: oController.onButtonPressed
});
return oButton;
}
点击的时候,调用 controller 中的 onButtonPressed 方法
控制器代码文件
控制器代码文件为 WebContent/zsapui5_button_mvc/master.controller.js。在Eclipse 中创建的 Controller, 起始代码如下:
sap.ui.controller("zsapui5_button_mvc.master", {
/**
* Called when a controller is instantiated and its View controls (if available) are already created.
* Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
* @memberOf zsapui5_button_mvc.master
*/
// onInit: function() {
//
// },
/**
* Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
* (NOT before the first rendering! onInit() is used for that one!).
* @memberOf zsapui5_button_mvc.master
*/
// onBeforeRendering: function() {
//
// },
/**
* Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
* This hook is the same one that SAPUI5 controls get after being rendered.
* @memberOf zsapui5_button_mvc.master
*/
// onAfterRendering: function() {
//
// },
/**
* Called when the Controller is destroyed. Use this one to free resources and finalize activities.
* @memberOf zsapui5_button_mvc.master
*/
// onExit: function() {
//
// }
});
我们看到,这些函数都被注释掉了,它们是 controller 生命周期中很重要的方法,我们后面再介绍,目前我们只需要加上 onButtonPressed() 方法。我把它写在最前面,后面的代码保持不动。当然,你也可以删除。
sap.ui.controller("zsapui5_button_mvc.master", {
onButtonPressed: function() {
jQuery.sap.require("sap.m.MessageBox");
sap.m.MessageBox.information("Hello from MVC.", {
title: "SAPUI5 MVC test"
});
}
/**
* Called when a controller is instantiated and its View controls (if available) are already created.
* Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
* @memberOf zsapui5_button_mvc.master
*/
// onInit: function() {
//
// },
/**
* Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
* (NOT before the first rendering! onInit() is used for that one!).
* @memberOf zsapui5_button_mvc.master
*/
// onBeforeRendering: function() {
//
// },
/**
* Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
* This hook is the same one that SAPUI5 controls get after being rendered.
* @memberOf zsapui5_button_mvc.master
*/
// onAfterRendering: function() {
//
// },
/**
* Called when the Controller is destroyed. Use this one to free resources and finalize activities.
* @memberOf zsapui5_button_mvc.master
*/
// onExit: function() {
//
// }
});
这样,就用 MVC 方式实现了和前面一样的功能。需要说明的时,Eclipse 的 Controller 代码是一种老式的代码。因为 SAP 已经停止对 Eclipse 开发插件的支持,所以也不会再更新。后面我们经常用的是 sap.ui.define 方法定义的 controller 代码。