ルーティング

Next2D FrameworkはシングルページアプリケーションとしてURLでシーンを制御できます。ルーティングはrouting.jsonで設定します。

基本設定

ルーティングのトッププロパティは英数字とスラッシュが使用できます。スラッシュをキーにCamelCaseでViewクラスにアクセスします。

{
    "top": {
        "requests": []
    },
    "home": {
        "requests": []
    },
    "quest/list": {
        "requests": []
    }
}

上記の場合:

  • topTopViewクラス
  • homeHomeViewクラス
  • quest/listQuestListViewクラス

ルート定義

基本的なルート

{
    "top": {
        "requests": []
    }
}

アクセス: https://example.com/ または https://example.com/top

セカンドレベルプロパティ

プロパティデフォルト説明
privatebooleanfalseURLでの直接アクセスを制御。trueの場合、URLでアクセスするとTopViewが読み込まれる
requestsarraynullViewがbindされる前にリクエストを送信

プライベートルート

URLでの直接アクセスを禁止したい場合:

{
    "quest/detail": {
        "private": true,
        "requests": []
    }
}

private: trueの場合、URLで直接アクセスするとTopViewにリダイレクトされます。プログラムからのapp.gotoView()でのみアクセス可能です。

requestsの設定

Viewがbindされる前にデータを取得できます。取得したデータはapp.getResponse()で取得できます。

requests配列の設定項目

プロパティデフォルト説明
typestringcontentjsoncontentcustomの固定値
pathstringemptyリクエスト先のパス
namestringemptyresponseにセットするキー名
cachebooleanfalseデータをキャッシュするか
callbackstring | arraynullリクエスト完了後のコールバッククラス
classstringemptyリクエストを実行するクラス(typeがcustomの場合のみ)
accessstringpublic関数へのアクセス修飾子(publicまたはstatic
methodstringempty実行する関数名(typeがcustomの場合のみ)

typeの種類

json

外部JSONデータを取得:

{
    "home": {
        "requests": [
            {
                "type": "json",
                "path": "{{api.endPoint}}api/home.json",
                "name": "HomeData"
            }
        ]
    }
}

content

Animation ToolのJSONを取得:

{
    "top": {
        "requests": [
            {
                "type": "content",
                "path": "{{content.endPoint}}top.json",
                "name": "TopContent"
            }
        ]
    }
}

custom

カスタムクラスでリクエストを実行:

{
    "user/profile": {
        "requests": [
            {
                "type": "custom",
                "class": "repository.UserRepository",
                "access": "static",
                "method": "getProfile",
                "name": "UserProfile"
            }
        ]
    }
}

変数の展開

{{***}}で囲むとconfig.jsonの変数を取得できます:

{
    "path": "{{api.endPoint}}path/to/api"
}

キャッシュの利用

cache: trueを設定すると、データがキャッシュされます。キャッシュしたデータは画面遷移しても初期化されません。 app.getCache()Map<string, unknown>を返し、requestsnameをキーにアクセスできます。

キャッシュ利用時のポイント:

  • 同じキーのデータが既にある場合は、リクエスト処理側がキャッシュ値を優先利用できます。
  • キャッシュは自動クリアされないため、不要なデータはdelete/clearで明示的に管理します。
{
    "top": {
        "requests": [
            {
                "type": "json",
                "path": "{{api.endPoint}}api/master.json",
                "name": "MasterData",
                "cache": true
            }
        ]
    }
}

キャッシュデータの取得:

import { app } from "@next2d/framework";

const cache = app.getCache();
if (cache.has("MasterData")) {
    const masterData = cache.get("MasterData");
}

コールバック

リクエスト完了後にコールバックを実行:

{
    "home": {
        "requests": [
            {
                "type": "json",
                "path": "{{api.endPoint}}api/home.json",
                "name": "HomeData",
                "callback": "callback.HomeDataCallback"
            }
        ]
    }
}

コールバッククラス:

export class HomeDataCallback
{
    constructor(data: any)
    {
        // 取得したデータが渡される
    }

    execute(): void
    {
        // コールバック処理
    }
}

画面遷移

app.gotoView()

app.gotoView(name?: string)で画面遷移を行います。戻り値はPromise<void>で、遷移先requestsの完了、View/ViewModelの再バインド、onEnter()まで待機できます。

gotoViewのポイント:

  • nameの型はstringです(省略可能、デフォルト値は"")。
  • nameにはrouting.jsonのキー(例: homequest/list)を指定します。
  • ?id=123のようなクエリ文字列を含めて渡せます。
  • 引数を省略した場合は、現在のURLから遷移先が解決されます(SPAのpopstate時)。
  • 遷移開始時に前回のresponseマップはクリアされます。
import { app } from "@next2d/framework";

// 基本的な遷移
await app.gotoView("home");

// パスで遷移
await app.gotoView("quest/list");

// クエリパラメータ付き
await app.gotoView("quest/detail?id=123");

UseCaseでの画面遷移

画面遷移はUseCaseで行うことを推奨します:

import { app } from "@next2d/framework";

export class NavigateToViewUseCase
{
    async execute(viewName: string): Promise<void>
    {
        await app.gotoView(viewName);
    }
}

ViewModelでの使用:

export class TopViewModel extends ViewModel
{
    private readonly navigateToViewUseCase: NavigateToViewUseCase;

    constructor()
    {
        super();
        this.navigateToViewUseCase = new NavigateToViewUseCase();
    }

    async onClickStartButton(): Promise<void>
    {
        await this.navigateToViewUseCase.execute("home");
    }
}

app.getContext()

app.getContext()で実行中のContextを取得できます。root(ルートSprite)、viewviewModelへの参照を持ち、遷移中はview/viewModelnullの場合があります。

import { app } from "@next2d/framework";

const context = app.getContext();
const root = context.root;

レスポンスデータの取得

app.getResponse()Map<string, unknown>を返します。requestsnameを設定したレスポンスを、現在の画面遷移単位で取得できます。

getResponseのポイント:

  • 1回のgotoViewで取得したデータの一時ストアです。
  • 次のgotoView開始時に内容は初期化されます。
  • 値の型はunknownなので、型ガードまたは型アサーションを行って利用します。
import { app } from "@next2d/framework";

async initialize(): Promise<void>
{
    const response = app.getResponse();

    if (response.has("TopText")) {
        const topText = response.get("TopText") as { word: string };
        this.text = topText.word;
    }
}

注意: responseデータは画面遷移すると初期化されます。画面を跨いで保持したいデータはcache: trueを設定してください。

SPAモード

config.jsonall.spaで設定します:

{
    "all": {
        "spa": true
    }
}
  • true: URLでシーンを制御(History API使用)
  • false: URLによるシーン制御を無効化

デフォルトのトップページ

config.jsonで設定:

{
    "all": {
        "defaultTop": "top"
    }
}

設定がない場合はTopViewクラスが起動します。

View/ViewModelの自動生成

routing.jsonの設定から自動生成できます:

npm run generate

このコマンドはrouting.jsonのトッププロパティを解析し、対応するViewとViewModelクラスを生成します。

設定例

完全な routing.json の例

{
    "top": {
        "requests": [
            {
                "type": "json",
                "path": "{{api.endPoint}}api/top.json",
                "name": "TopText"
            }
        ]
    },
    "home": {
        "requests": [
            {
                "type": "json",
                "path": "{{api.endPoint}}api/home.json",
                "name": "HomeData"
            },
            {
                "type": "content",
                "path": "{{content.endPoint}}home.json",
                "name": "HomeContent",
                "cache": true
            }
        ]
    },
    "quest/list": {
        "requests": [
            {
                "type": "custom",
                "class": "repository.QuestRepository",
                "access": "static",
                "method": "getList",
                "name": "QuestList"
            }
        ]
    },
    "quest/detail": {
        "private": true,
        "requests": [
            {
                "type": "custom",
                "class": "repository.QuestRepository",
                "access": "static",
                "method": "getDetail",
                "name": "QuestDetail"
            }
        ]
    }
}

関連項目