FuelPHPはMVC(Model、View、Controller)フレームワークとして知られていますが、『ビューモデル(ViewModel)』というオプションが存在します。
その名の通り、ViewとModelの中間の担うクラスなのですが、今回はその利用方法を勉強したいと思います。
※実際のイメージではControllerとViewの間?
「ビューモデル」とは?
「ビューモデルとは?」ですが、
例えばMVCで構築する場合、任意のテーブルの情報を取得し画面に一覧として表示する処理を考えます。
Controller内でModelからデータを取り出し、HTMLコードで整形し、Viewに渡して表示させます。
それに対して以下のような意見が出ることがあるでしょう。
「HTMLの整形はビューでやるべきでコントローラの中でHTMLタグを扱うべきではない」
一方で、ModelのデータをViewに渡して、View内でループさせたり値のフォーマットを調整したりしてHTMLを整形させます。
そうすると以下のような意見もあります。
「View内では表示処理のみで、あれこれロジックを組むべきではない」
はたまたこんな事言う人も。
「Modelはそれ自身の役割があるからController内(またはView内)で呼び出すべきじゃない」
。。。決めの問題で、どっちでもいい気がします。
そんな時、そんな処理はViewModelに記述しましょう!
ViewModelクラスを用意する
まずViewModelクラスを用意します。
基本的にビューファイル1つにつき、1クラス用意するほうがよいでしょう。
例えばホームページのビューファイル「/app/views/welcome/index.php」にViewModelクラスを適用する場合、「/app/classes/view/welcome/index.php」を用意します。
class View_Welcome_Index extends ViewModel{ public function view(){ $this->title = "サンプルタイトル"; } }
クラス名はFuelPHPの命名ルールに従い、クラス「ViewModel」を継承します。
関数は基本的に「view()」のみ設置します(例外、拡張あり)。
ビューに渡す値はthisに格納します。
Controllerを準備する
次にコントローラ内で、アクション毎にビューモデルを使用することを宣言します。
通常、コントロール「/app/classes/controller/welcome.php」内でビューに値を渡す場合は以下のように記述します。
class Controller_Welcome{ public function action_index(){ return View::forge('welcome/index'); } }
これを先ほど用意したビューモデルを使用する場合は以下のように記述します。
return ViewModel::forge('welcome/index');
既存の処理も簡単に切り替えられますね。
これで一通りViewModelの適用は完了です。
ビューファイル「/app/views/welcome/index.php」に以下のように記述すれば、「サンプルタイトル」が表示されます。
echo $title;
ちなみにテンプレートを使用する場合にも、以下のように簡単に適用できます。
class Controller_Welcome extends Controller_Template{ public function action_index(){ $this->template->content = ViewModel::forge('welcome/index'); } }
まとめ
ViewModelはうまく活用できるかどうか?
ViewModelオプションは、複雑な処理が多い画面については有効だと思います。
「コントローラクラスが処理で膨大になる」「ビューファイルがPHPソースでごちゃごちゃでHTMLを読み取ることができない」そういった事を防ぐために、ViewModelに処理をうまくまとめれば、コードもスッキリするでしょう。
一方で、ほとんどロジックのないシンプルなページだと、クラスファイルが増えるだけなので、無理に適用する必要はないです。
ページ毎に気軽に導入できるオプションなので、適材適所で判断すればよいと思います。
Presenterクラスというのがある
ViewModelは将来的に、同等の機能であるPresenterクラスに集約されるようです。
今回の確認環境はFuelPHP 1.7.3です。
Presenterクラスは1.7.2から利用でき、本格的なリリースは1.8からのようです。
では今回、Presenterでよかったのではないかというお話ですが、1.7.xではうまく動作しなかったりと不具合の元になるようです。
1.7.xではViewModel、1.8.xではPresenterを利用するほうがいいかもしれません。
コメントする