Routingとは
Routingは、SAPUI5アプリのナビゲーションで使う技術です。今回はRoutingの概念、実装について説明します。
Routingでは、ビューまたは複数のビューのまとまりをRouteと呼びます。
Routingとは、RouteからRouteへ移動する際に「どんなURLで」「どこのビューへ」遷移するのかを定義するものです。
ハッシュついて
Routeは固有のURLを持ちます。#の後にそれぞれのビューに固有のパラメータがつきます。この部分をハッシュと呼びます。以下のようなイメージです。
一覧画面 ...#/list
詳細画面 ...#/detail/0
URLが変わるので、ブラウザの履歴にそれぞれのURLが保持されます。このおかげでブラウザの「戻る」「進む」ボタンを使って前の画面に戻ったり、次の画面に進んだりすることが可能です。これはWebDynrpoやBSPにはない特徴です。
Routingの実装
ゴール
構成
Routingのために実装する箇所は以下の4点です。
ステップ
前提:入門編の記事まとめ
0.事前設定
1.Routingの定義
2.Routerを初期化
3.Routerのナビゲーションメソッドを呼び出し
4.選択された行に対するモデルをバインド
0. 事前設定
モデル、ビュー、コントローラーを作ります。
Data.json
{
"Products": [
{
"name": "あずきもなか",
"price": 105,
"currency": "JPY",
"ingredients": "牛乳、砂糖、小豆",
"producer": "大納言農場"
},
{
"name": "いちごアイス",
"price": 120,
"currency": "JPY",
"ingredients": "牛乳、砂糖、いちご",
"producer": "とよのかファーム"
},
{
"name": "ヨーグルトアイス",
"price": 160,
"currency": "JPY",
"ingredients": "ヨーグルト",
"producer": "カスピ海工房"
}
]
}
このモデルをデフォルトビューとしてmanifest.jsonに設定
"models": {
"":{
"type": "sap.ui.model.json.JSONModel",
"uri": "model/Data.json"
}
}
App.view.xml(一覧画面)
<mvc:View
controllerName="template.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<App id="idApp">
<pages>
<Page title="{i18n>pageTitle}">
<content>
<List
items="{/Products}" id="idList" headerText="アイスクリーム"
selectionChange="onSelect" mode="SingleSelectMaster">
<items>
<ObjectListItem
type="Navigation"
title="{name}"
number="{
parts:[{path:'price'},{path:'currency'}],
type: 'sap.ui.model.type.Currency',
formatOptions: {showMeasure: false}
}"
numberUnit="{currency}">
</ObjectListItem>
</items>
</List>
</content>
</Page>
</pages>
</App>
</mvc:View>
Detail.view.xml(詳細画面)
<mvc:View controllerName="template.controller.Detail" xmlns="sap.m" xmlns:f="sap.ui.layout.form" xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core">
<App id="idApp">
<pages>
<Page title="{i18n>detailPageTitle}">
<content>
<f:SimpleForm id="SimpleForm" editable="true" title="商品詳細">
<f:content>
<Label text="商品名"/>
<Text id="name" text="{name}"/>
<Label text="価格"/>
<Text id="price" text="{price} {currency}"/>
<Label text="原料"/>
<Text id="ingredients" text="{ingredients}"/>
<Label text="生産者"/>
<Text id="producer" text="{producer}"/>
</f:content>
</f:SimpleForm>
</content>
</Page>
</pages>
</App>
</mvc:View>
1. Routingの定義
manifest.jsonのsap.ui5セクションに以下のコードを追加します。
"sap.ui5": {
"_version": "1.2.0",
"rootView": {
"viewName": "template.view.App",
"type": "XML",
"id": "app"
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewPath": "template.view",
"viewType": "XML",
"controlId": "idApp"
},
"routes": [
{
"pattern": "",
"name": "root",
"target": ["t_root"]
},
{
"pattern": "detail/{index}",
"name": "detail",
"target": ["t_detail"]
}
],
"targets": {
"t_root": {
"viewName": "App",
"viewId": "idViewApp",
"controlAggregation": "pages"
},
"t_detail": {
"viewName": "Detail",
"viewId": "idViewDetail",
"controlAggregation": "pages"
}
}
},
Routingは以下3つのセクションに分かれています。
今回使用しているパラメータは一例で、詳しくは以下のページをご参照ください。
Routing Configuration
config
- routerClass: 固定でsap.m.routing.Routerを指定
- viewPath: ビューのファイルが格納されているフォルダパス
- viewType: ビュータイプ
- controlId: ビューを表示するのに使われるコントロールのID。今回はAppコントロールを使用するので、Appコントロールのidである"idApp"を指定
※viewPath以下はtargetsのパラメータの初期値で、targets側で個別に定義することも可能
routes
- name: ルート名
- pattern: ハッシュを指定する。{ }で囲むことで変数も指定可能。今回の場合、indexに指定された値がハッシュの一部となる。(変数名は任意)
- target: targetsセクションで定義したtargetの値を指定する。Master Detail画面のように一つの画面に複数ビューを表示するときは複数指定する。
targets
- viewName: ビュー名
- viewId: ビューのID。ビュー側であらかじめ定義する必要はなく、ここで定義するだけでよい
- controlAggregation: どのaggregationにビューを追加するかを定義。今回はApp配下のpages aggregationに追加するので、pagesを指定
2. Routerを初期化
Component.jsの初期化メソッドの中で、Routerの初期化を行います。
sap.ui.define([
"sap/ui/core/UIComponent"
], function (UIComponent) {
"use strict";
return UIComponent.extend("template.Component", {
metadata : {
manifest: "json"
},
init : function () {
// call the init function of the parent
UIComponent.prototype.init.apply(this, arguments);
// Routerを初期化
var oRouter = this.getRouter();
oRouter.initialize();
}
});
});
3. Routerのナビゲーションメソッドを呼び出し
Appビュー(一覧を表示)の中で、以下の処理を実装します。
①Routerオブジェクトを取得
App.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
], function (Controller) {
"use strict";
return Controller.extend("template.controller.App", {
onInit: function(){
this.oRouter = this.getOwnerComponent().getRouter();
}
});
初期処理の中で、Routerオブジェクトを取得しておきます。
②行が選択されたときに呼ばれるメソッドを実装
onSelect: function(oEvent){
//選択された行のパスを取得:/Products/2 のような形で取得される
var sPath = oEvent.getParameter("listItem").getBindingContextPath();
//indexに上記パスからインデックスの部分を取得
var index = sPath.split("/")[sPath.split("/").length - 1];
//Routerオブジェクトを使って詳細画面へ遷移する
this.oRouter.navTo("detail", {
index: index
});
}
RouterオブジェクトのnavToというメソッドを使って、detailに移動します。
detailというのはroutingの設定で定義したrouteの名前です。detailのpatternは以下のようになっていました。
"pattern": "detail/{index}"
変数indexを引数に取りますよ、と宣言しているのでnavToメソッドにindexを渡します。
4. 選択された行に対するモデルをバインド
Detailビューでは、一覧で指定された行に対応する商品の詳細を表示すします。このために、引数に渡された値をもとにモデルへのパスを作ってビューにバインドします。以下の処理を実装します。
①Routerオブジェクトを取得(Appと同様)
②RoutePatternMatchedイベントをイベントハンドラを登録
Detail.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
], function (Controller) {
"use strict";
return Controller.extend("template.controller.Detail", {
onInit: function(){
//Routerオブジェクトを取得
this.oRouter = this.getOwnerComponent().getRouter();
//ルートがマッチしたときのイベントハンドラを登録
this.oRouter.attachRoutePatternMatched(this._matched, this);
}
});
});
RoutePatternMatchedイベントは、実行されたURLのハッシュ部分がRoutingの定義の中で定義されたいずれかのパターンに一致した場合に発火します。パターンにマッチした場合はこのあと定義する_matchedメソッドが呼ばれます。
一覧画面から遷移する場合だけでなく、直接このURLが実行された場合でもRoutePatternMatchedがトリガされます。
③_matchedの実装
_matched: function(oEvent){
//呼び出し元画面で指定された引数を取得
var index = oEvent.getParameter("arguments").index;
//パスを作成:/Products/2のような形に
var sPath = "/Products/" + index;
//パスをビューにバインド
this.getView().bindElement(sPath);
}
実行結果
アプリを実行します。ここでは、アドレスバーに注目してください。
一覧画面ではハッシュはついていません。一覧画面のrouteのパターンが""となっているためです。
ここで、0を1に変えてみます。
すると、2番目の商品の詳細が表示されました。このように直接URL指定でもビューを切り替えることができます。
まとめ
- SAPUI5では、ナビゲーションにRoutingを使う
- Routingの定義は、config, routes, targetsからなる
- ハッシュが変わることで、ブラウザの履歴を使ったナビゲーションが可能になる