階層構造
今回は階層構造について説明します。
その1で何回か述べた通り、Router
を持つヒエラルキーは入れ子構造にできます。
これによって、
/PageA/a/e
/PageA/b/f
/PageB/c
/PageB/d
/PageC
というパスでアクセスできることになります。もちろん、末端ノードでない/pageA
、/PageB
、/PageA/a
、/PageA/b
にもJumpTo
できます。
enterとleave
パスヒエラルキーに含まれる各Router
は、enterとleaveという内部イベントを処理します。この知識はトリガを扱うときにも必要になることがあるので説明しておきます。
おおむね、JumpTo
である場所に来たらその場所にenterが、ある場所から離れるとその場所にleaveが発生すると考えて下さい。
例えば、まず
Routing.JumpTo("/PageA/a/e");
したとしましょう。次に、
Routing.JumpTo("/PageA/b/f");
したとします。
このとき、/PageA/a/e
でleaveトリガが発生し、/PageA/b/f
でenterトリガが発生します。
中間ノードにおけるenter/leave
routeneではさらに、上記のケースで、中間ノードであるa
やb
でもleave/enterが発生します。/PageA
ではenterもleaveも発生しません。この動きをファイルシステムのディレクトリにたとえて言うと、cdで一手ずつ相対移動するときの最短距離でのみ処理が行われると考えればよいかと思います。
例えば、/PageA/a/e
から/PageA/b/f
への移動は、
% cd ..
% cd ..
% cd b
% cd f
となります。cd ..
したときに移動前の場所でleaveが、cd <dir>
としたときに移動後の場所でenterが発生します。
実装方法
routeneでは、このイベントの伝播のために、UniRxを使っています。具体的には、Router.csの以下のような定義によってです。
[NonSerialized] public BehaviorSubject<Plan> enter =
new BehaviorSubject<Plan>(null);
[NonSerialized] public BehaviorSubject<Plan> leave =
new BehaviorSubject<Plan>(null);
Routing.JumpTo("/A/B")
のような要求がきたとき、Routing
はこれを識別子のリスト["A","B"]
に分解し、concreteRouterに渡します。
受け取ったRouterでは、リストの先頭を消費してのこりをthis.enter
にUniRxのイベントとして発行します。子Router
は親のRouter
のenter/leaveをStart
時に自動的にObserve
しますので、同様に再帰的に処理していきます。
なぜこのような構造にしたかというと、動的なmountを実現するためです。そのあたりは次回説明します。
leaveについては、enterと同じようなことを前回与えられたパスに対してenterの前に行うことで実現されます。