メニュー構築パターン


9

メニューがルーティングに使用されていない場合、メニューのアクティブ状態の処理に頭を悩ませています。

メニューシステムがルーティングも処理するDrupalから来ました。したがって、アクティブ状態とアクティブトレイル状態の設定は、ルートによって処理されます(これはメニューレンダリングシステムとしても機能します)。

現在、多くのPHPフレームワークには、ルーティングを処理するルータークラスがあります。メニューはPOSTを認識してはならないため、これは良い分離のようです|| オプション|| ... リクエスト。

しかし、フロントエンドを書いているとき、メニューをハードコーディングしていることに気づきました。または、すべてをDBに保存し、それらの値をビューに渡します。このアプローチが嫌いなのは、ルーターで既に書き込んだもののコピーを作成しているが、現在はMenuクラスを使用していることです。

例:

Route::get('/somewhere','routename.somewhere','showStuffController');
Route::post('/somewhere','routename.somewhere','saveStuffController');

Menu::add('label.somewhere','routename.somewhere');

ここで懸念を分離しているので、それは素晴らしいことです。しかし、MenuはRouteに大きく依存して、アクティブ状態を設定します。メニューは、アクティブトレイルを設定するための階層についても知る必要があります。

つまり、アクティブなトレイルとアクティブなステータスクラスを設定することは、実際にはビューのことです。しかし、

if ( Route::currentName() === $menuitem->getRouteName() ) { print 'active'; }

あなたの意見の至る所で愚かに思えます。次に、迷惑なアクティブトレイルをすべて追加します。ビューがレンダリングされる前にそれを処理し、active-trailフラグをtrueに設定することは、私が知っている方法では非常に醜いようです(すべての子をループするforeachループ、...)

私の質問は:

このよりきれいな、より良い、...を得るパターンまたはスマートな方法はありますか?アクティブトレイルの「問題」をどのように処理する必要がありますか?

子->親のレンダリングを考えていました。したがって、最も深いレベルの広告から始めて、次の段階に進みます。しかし、子供はその親について知っていますが、親は自分の子供については何も知りません(変なようです)。

回答:


1

メニューがルーティングに使用されていない場合

メニューにはルーティング使えると思います。


すでに指摘したように、ルーターはフックするのに最適な場所です。各リクエストで現在のページのメニューメタを評価するフックを使用することは醜いとは思わないでしょう。

アクティブな状態を追跡する責任をビューに持たせても、懸念を分離することはありません。ビューは目的に応じて何をする必要がありますが、メニューの状態も管理する必要はありません。メニューのメタデータは通常、アプリケーション全体で同じであり、自分自身を見つけてメニューをレンダリングできるようにするためのルートのみが必要です。

ルーターと必要に応じて、いくつかの静的メニューメタデータを取得する単純な関数またはクラスと現在のルートで、後で必要なすべての情報を提供できます。

メニューメタ自体は、必ずしもオブジェクトである必要はありません。ほとんどの場合、メソッドのない単純なキー値データ構造で十分です。

フックは、ブレッドクラム、深さ、親ページ、現在のページなど、メニューに関連するいくつかの一般的な機能を持つ状態オブジェクトを作成し、このオブジェクトをhttpリクエストのコンテキストで認識させることができます。フックの内部にはさまざまな可能性がありますが、一般的には、必要なデータを収集して準備し、それを処理する方法を知っているものに渡すことです。

このアプローチはニーズに応じて拡張され、いくつかの利点があります。

  1. データベースはデータを処理する必要がなく、実行時に低コストで提供できます
  2. メニュー(メタ)が1か所にあり、保守しやすい
  3. メニューをルートに完全に1:1で依存させたい場合は、メニューメタを動的に提供することで実現できます。
  4. コンテンツが大きくなった場合は(したがってメニューも)、このデータをセッションに移動できます。セッションは高速キー値ストアに書き込まれる可能性があります
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.