3

Yiiフレームワークを使用して、2列のレイアウトを使用するサイトを開発しています。1つの列は実際のコンテンツであり、もう1つの列はサイトリンク、ログインしたユーザーに関する情報、および最新の投稿のリストを含むメニューです。メニューはすべてのページに表示されますが、現在のページ(またはルート)に関連する情報はありません。

メニューをレンダリングするたびに、データベースから最新の投稿とユーザー関連データのリストを取得する必要があります。サイト上のすべてのアクションでデータをフェッチするコードを繰り返さないように、このメニューをどのようにレンダリングするのが最適かわかりません。

私はいくつかのアプローチを考えましたが、そのうちのどれがこの状況に対処する正しい方法であるかを知りたいと思います。

  • メソッド内のデータをフェッチしてから、データをブロックController::beforeRenderに表示する部分ビューでメニューをレンダリングします。CClipWidget次に、レイアウトビューで、メニューがあるはずのブロックを表示します。この方法は機能しますが、のせいでかなり不格好だと思いbeforeRenderます。メニューがないページを追加した場合は、そのチェックを含める必要があります。また、Yiiのドキュメントを読んだ後、が必要なのか、それとも単に。beforeRender()が必要なのかわかりません。renderPartial()render()

  • メニューの部分的なビューを保持し、レイアウトビューからレンダリングします。データは、別の場所(おそらくモデル内)に配置された静的メソッドからメニュービューにフェッチされます。これにはごくわずかなコードの記述が含まれますが、MVCパラダイムに適しているかどうかはわかりません。ビュー内のデータをフェッチすると、静的関数を呼び出しているだけなのに、少しうんざりします。

  • メニューをウィジェットに変えます。データはrun()メソッドでフェッチされ、ウィジェットビューからレンダリングされます。ただし、ウィジェットを使用すると、いくつかの追加の制限が課せられます。コントローラで最新の投稿をレンダリングするビューを使用したい場合、問題が発生します。ウィジェットは使用できず、常にrenderPartial()使用する必要がありrender()ます。render()ビュー(ウィジェットまたはコントローラー)をレンダリングしているものを確認し、またはrenderPartial()適切に呼び出す方法を理解すれば、これを回避できます。また、ウィジェットビューはサイトビューから分離する必要がありますが、のように完全なビューパスを指定することで、これを回避できapplication.views.controller.viewます。さらに、ウィジェットがデータベースデータを自分でフェッチする必要があるかどうかはまだわかりません。

これらの方法はすべて機能しますが、いくつかの問題があります。多くのサイトが同じ状況にあると確信しており、最良の選択肢が何であるかを知りたいと思います。

4

1 に答える 1

1

データベースの結果をキャッシュするだけで、このデータを再リクエストすることによるパフォーマンスへの影響のほとんどを回避できるはずです(メモリまたはファイルのいずれかで、ユーザーとセットアップに依存します)。小さくて簡単な例を次に示します。

$posts = Post::model()->cache(600)->with('comments')->findAll(array('blah=blahdyblah'));

これにより、返されたデータが10分間キャッシュされます。

完全を期すために、Yiiキャッシングガイドへのリンクを次に示します。 キャッシングガイド

すべてのページでこのデータを実際に取得するには、コードを独自のウィジェットに配置し、レイアウトファイルのどこかで呼び出すことをお勧めします。

リストしたウィジェットの制限は、次のように処理できます。

  • まず、ウィジェットがレンダリングされるとき、それはrender()レイアウトなしでのみ表示されます。これはほとんどの場合問題ありませんが、それだけをオンにしたページが必要な場合、たとえば実際のページが必要な場合は、render()まさにそれを実行し、そのウィジェットのみを呼び出すビューを作成します。

  • 第二に、ウィジェットをアプリケーションから完全に抽象化し、そのデータとモデルを使用しないようにする必要がある理由はありません。はい、それは「プラグイン可能」であることができるという非常に素晴らしい機能ですが、それはそれらがそうである必要があるという意味ではありません、あなたはコードを分離するためにそれらを使用しているだけです。

  • 最後に、ウィジェットからのデータの「一部」を使用したいが、すべてではない場合、または少し変更したい場合は、ウィジェット内で使用するメソッドとビューは、必要な部分を使用できる十分な抽象化で構築する必要があります別々に。これを行う良い方法はscopes、ActiveRecords、ミニビューファイルをうまく利用し、非データロジックのより大きなチャンクにコンポーネントを使用することです。

もちろん、実際にパフォーマンスの限界で実行していて、リクエスト時間を1000分の1秒短縮する必要がある場合は、ビューのキャッシュとビューのフラグメントキャッシュの使用を検討する必要があります。

于 2012-08-10T09:15:14.290 に答える