はじめに
単画面のアプリならルーティングは不要ですが、実業務で使うアプリは「一覧→詳細→編集」のように複数画面を行き来するのが普通です。SAPUI5にはこのナビゲーションを宣言的に扱える Routing 機能が組み込まれており、manifest.jsonの設定だけで複雑な画面遷移が作れるのが特徴です。
この記事では、Routingの基本概念と、現場で使う3つの典型的な画面遷移パターンを整理します。
Routingの登場人物
Route(ルート)
URLパターンと、それに対応するTargetを紐付ける定義です。/customers にアクセスされたらCustomerList Viewを表示、という対応付けを行います。
Target(ターゲット)
表示すべきViewと、そのコンテナ(どこに表示するか)を定義します。同じViewを複数Routeから再利用できます。
Router(ルーター)
manifest.jsonの設定を読み込み、URL変更をイベント化してController側に通知するランタイムオブジェクトです。Component.jsで this.getRouter() から取得できます。
manifest.jsonでの基本定義
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"viewPath": "app.view",
"controlId": "app",
"controlAggregation": "pages",
"transition": "slide"
},
"routes": [
{ "name": "list", "pattern": "", "target": "list" },
{ "name": "detail", "pattern": "customers/{id}", "target": "detail" }
],
"targets": {
"list": { "viewName": "Main" },
"detail": { "viewName": "Detail" }
}
}
patternの中括弧はパラメータで、customers/123 のようにアクセスされると {id} に 123 が渡ります。
Controller側の操作
ルートへの遷移
this.getOwnerComponent().getRouter().navTo("detail", { id: "123" });
Routeが一致したときのハンドリング
onInit: function() {
this.getOwnerComponent().getRouter()
.getRoute("detail")
.attachPatternMatched(this._onDetailMatched, this);
},
_onDetailMatched: function(oEvent) {
var sId = oEvent.getParameter("arguments").id;
this.getView().bindElement("/customers('" + sId + "')");
}
詳細画面のControllerでは、URLが一致したタイミングでバインディングを張り直すのが定番のパターンです。
戻る操作
var oHistory = sap.ui.core.routing.History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
this.getOwnerComponent().getRouter().navTo("list", {}, true);
}
ブラウザ履歴がある場合は戻る、ない場合は明示的にリストにnavToする、というのがFiori標準の書き方です。
Flexible Column Layoutでのマスタ/詳細
Fioriではマスタ/詳細を横並びに表示するFlexible Column Layout(FCL)が標準パターンです。
flowchart LR U[URLパターン] --> R1["list
/customers"] U --> R2["detail
/customers/{id}"] U --> R3["detailDetail
/customers/{id}/orders/{oid}"] R1 --> T1["Begin Column
顧客一覧"] R2 --> T2["Mid Column
顧客詳細"] R3 --> T3["End Column
注文詳細"]
FCLは3カラムまで同時に表示可能で、画面の広さに応じて自動的に列を折り畳みます。manifest.jsonでは各Targetに controlAggregation: "beginColumnPages" のように配置先カラムを指定します。
パラメータの種類
- 必須パラメータ:
pattern: "customers/{id}"— URLに含まれないとRouteが一致しない - オプションパラメータ:
pattern: "customers/{id}/:mode:"— あってもなくてもOK - クエリパラメータ:
pattern: "customers/{id}?{query}"—?filter=activeのような形式
実務では必須パラメータが大半です。オプション・クエリは特殊な用途(編集モード切替、フィルタ状態の保持)でのみ使います。
よくある疑問
Q. hashChangeイベントとattachPatternMatchedの違いは?
A. hashChangeはブラウザ全体のハッシュ変化を捕捉し、attachPatternMatchedは「このRouteに一致したとき」だけ発火します。Controllerで詳細表示処理を書くときは後者が基本です。
Q. ルーティング中にデータ取得が遅いとどうなりますか?
A. 画面は即座に切り替わり、バインディング対象がまだ空の状態で表示されます。Busy Indicator(this.getView().setBusy(true))を組み合わせるのが標準対処です。
Q. ディープリンク(URL直接指定)で開いてもいいですか?
A. 問題ありません。ただし初回ロード時にそのURLに必要なデータがロードされるまで画面が空になるので、Busy状態の制御が重要です。
Q. Fiori Elementsでもルーティングは自分で書く必要がありますか?
A. Fiori Elementsは List Report + Object Page のルーティングを自動生成します。manifest.json設定だけで遷移が動き、Controllerはほぼ書かなくて済みます。
まとめ
- Routing = Route(URLパターン)+ Target(表示View)+ Router(ランタイム)
- manifest.jsonで宣言的に定義し、Controllerから navTo で遷移
- パターンマッチ時は attachPatternMatched でバインディング更新
- Flexible Column Layoutは3カラム構成のマスタ/詳細パターン
- Fiori Elementsを使えばルーティングは大半が自動生成される
次はSAPUI5 フラグメント・カスタムコントロールで、View再利用の仕組みを見ていきます。
ルーティングの設定やFlexible Column Layoutの実装を、座学だけでなく手を動かして覚えたい方にはハンズオン講座がおすすめです。UI5アプリの構築からBTPへのデプロイまで一貫して学べます。