はじめに
SAPUI5をしばらく触ってみて、MVCはレストランに似ていると感じました。
MVC、レストランと検索すると以下のようなページが出てきたので、そう感じるのは私だけではないようです。
図解!どのサイトを見てもわからなかった人のためのMVC
MVCフレームワークって?
MVCとかWAFとかを最初に理解するにあたってイメージしたこと
これらのページでは、Model, View, Controllerは以下のものに例えられています。
- Model: コックさん
- View: ウェイター or お客さん or 料理
- Controller: ホールスタッフ
共通してるのは、Modelが処理ロジックであり、Controllerはデータをどこに届けるかを決める役割をしているという点です。
SAPUIの場合
SAPUI5ではModelとはデータであり、処理ロジックはControllerが担います。よって、以下のイメージのほうが近いのではないかと考えます。
ここではデータ=料理とします。
- Model: メニュー・・・データの構造や内容を定義したもの
- View: お客さん・・・データを消費する
- Controller: コックさん・・・モデルをインスタンス化してビューに渡す
以下はシンプルなJSONモデルの例です。データの中身も見えていてそのまま使えそうですが、実はモデルはインスタンス化しないと使うことができないのです。(manifest.jsonを利用することによりインスタンス化を意識しないで済みますが)
そんなわけで、「Model=メニュー」のほうがSAPUI5ではしっくりくると思いました。
{
"product" : {
"name" : "pumpkin",
"price": 150
}
}
Model, View, Controllerのシンプルなアプリケーションを作ってみる
manifest.jsonファイルなどを使わない、シンプルなアプリケーションを作ってみます。
ゴール
「本日の定食」を表示する画面を作ります。
作成するファイル
- index.html
- Model
- View
- Controller
フォルダ構成
index.html
まずはbootstrapの部分を作ります。(bootstrapについてはこちら)
<!DOCTYPE html>
<html>
<head>
<!-- bootstrap of SAP UI5 -->
<script
id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m, sap.ui.layout"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-resourceroots='{
"restaurant": "./"
}'>
</script>
<script>
//ビューを生成する
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>
「ビューを生成する」のコメントのところに、"customer.view.xml"のビューをbodyに配置するという内容のコードを追加します。
var oFirstView = new sap.ui.view("idCustomer", {
viewName: "restaurant.view.customer",
type: sap.ui.core.mvc.ViewType.XML
});
oFirstView.placeAt("content");
Model
本日の定食のモデル(menu.json)を作成します。簡単にするためにメニューは1つだけです。
{
"menu":
{
"name": "焼き魚定食",
"price": 850,
"calories": 500
}
}
View
定食を待っているお客さんを表すビュー(customer.view.xml)を作成します。
Textコントロールにメニューの項目をバインドします。
<mvc:View
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:f="sap.ui.layout.form"
controllerName="restaurant.controller.customer">
<App id="idApp">
<Page title="本日の定食">
<content>
<f:SimpleForm>
<f:content>
<Label text="メニュー"></Label>
<Text text="{/menu/name}"></Text>
<Label text="価格"></Label>
<Text text="{/menu/price}"></Text>
<Label text="カロリー"></Label>
<Text text="{/menu/calories}"></Text>
</f:content>
</f:SimpleForm>
</content>
</Page>
</App>
</mvc:View>
Controller
customer.controller.jsファイルを作成します。メニューの料理を作ってお客さんに渡します。
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"
], function(Controller, JSONModel){
return Controller.extend("restaurant.controller.customer", {
onInit: function(){
//モデルをインスタンス化(メニューから料理を作る)
var oModel = new JSONModel();
oModel.loadData("model/menu.json");
//モデルに名前を設定(名無しなのでデフォルトモデルになる)
sap.ui.getCore().setModel(oModel);
}
});
});
まずは空のJSONモデルのインスタンスを作って、そこにデータを流し込みます。
setModelメソッドにより、このアプリケーションでモデルにアクセスできるようにします。
結果
余談
ところで、「モデルを使うためにコントローラーって本当にいるの?」って思いませんか?
ビューでデータのパスを指定しているし、そのまま読み込めそうな感じがします。
そこで、コントローラの処理をコメントアウトしてみます。
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"
], function(Controller, JSONModel){
return Controller.extend("restaurant.controller.customer", {
onInit: function(){
/* //モデルをインスタンス化(メニューから料理を作る)
var oModel = new JSONModel();
oModel.loadData("model/menu.json");
//モデルに名前を設定(名無しなのでデフォルトモデルになる)
sap.ui.getCore().setModel(oModel);*/
}
});
});
結果
定食が消えてしまいました。やはり、モデルは料理(インスタンス化)しないと使えないことがわかりました。
まとめ
- 一般的なMVCと、SAPUI5のMVCではModelの役割が異なる
- SAPUI5ではデータを定義した「メニュー」(あるいはカタログ)のようなもの
- Modelは定義するだけでは使えず、インスタンス化する必要がある