LoginSignup
2
4

More than 3 years have passed since last update.

【SAPUI5】Routingとナビゲーション

Last updated at Posted at 2019-02-11

Routingとは

Routingは、SAPUI5アプリのナビゲーションで使う技術です。今回はRoutingの概念、実装について説明します。

Routingでは、ビューまたは複数のビューのまとまりをRouteと呼びます。
Routingとは、RouteからRouteへ移動する際に「どんなURLで」「どこのビューへ」遷移するのかを定義するものです。
image.png

ハッシュついて

Routeは固有のURLを持ちます。#の後にそれぞれのビューに固有のパラメータがつきます。この部分をハッシュと呼びます。以下のようなイメージです。
一覧画面 ...#/list
詳細画面 ...#/detail/0
URLが変わるので、ブラウザの履歴にそれぞれのURLが保持されます。このおかげでブラウザの「戻る」「進む」ボタンを使って前の画面に戻ったり、次の画面に進んだりすることが可能です。これはWebDynrpoやBSPにはない特徴です。

Routingの実装

ゴール

行を選択すると詳細画面に遷移するアプリを作ります。
image.png

image.png

構成

Routingのために実装する箇所は以下の4点です。
1. manifest.json
2. Component.js
3. 移動元ビューのコントローラー
4. 移動先ビューのコントローラー
image.png

ステップ

前提:入門編の記事まとめ

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を指定

config, routes, targetsの関係
image.png

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のパターンが""となっているためです。

image.png

詳細画面では、#のあとに/detail/0と表示されます。
image.png

ここで、0を1に変えてみます。
すると、2番目の商品の詳細が表示されました。このように直接URL指定でもビューを切り替えることができます。
image.png

まとめ

  • SAPUI5では、ナビゲーションにRoutingを使う
  • Routingの定義は、config, routes, targetsからなる
  • ハッシュが変わることで、ブラウザの履歴を使ったナビゲーションが可能になる
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4