2

MVC パターンで、単一のビューに同じタイプの複数のアクション (POST など) が含まれる可能性がある場合の最適な処理方法は何ですか?

たとえば、TODO リスト アプリケーションで考えてみましょう。ユーザーが複数のリストを作成できるようにする場合があります。各リストには複数のアイテムを含めることができます。したがって、ユーザーは site.com/list/1 に移動し、最初のリストのすべてのアイテムが表示されます (1 は GET パラメーターです)。このページには、ユーザーが次のことを行えるようにするための 2 つのフォーム (POST) があります。

  1. 新しいアイテムを作成する
  2. 既存のアイテムを削除する

ブートストラップが「listcontroller」を作成する必要がある場合は、POST 変数を調べてから、次のような適切なメソッドを呼び出します。

$lc = new ListController();    
if(strtolower($request->verb) === 'post'):
    if(isset($_POST['title'])) :
        $data = $lc->newItem($_POST);
        $load->view('newitem.php', $data);
    else if(isset($_POST['delete']) && isset($_POST['id'])):
        $data = $lc->deleteItem($_POST);
        $load-view('deleteitem.php', $data);                    
    endif;// End if post title
else:
    //GET request here so show view for single list
endif; //

それとも、次のようなことをしたほうがいいですか

$lc = new ListController();
if(isset($_POST)):
    //controller handles logic about what function to call
    $data =  $lc->PostAction($_POST); 
    // $data could also potentially hold correct view name based on post
    $load->view(); 
else:
    //again just show single list
endif;

さまざまなシナリオを処理するためのネストされた if/else または case ステートメントがかなりある可能性があるため、コントローラーが複数の異なるアクションを潜在的に処理できるようにする最善の方法に苦労しています。私はこれらがどこかに座らなければならないことを知っていますが、どこが最もきれいですか?

そこには多くのフレームワークがあることを知っていますが、その背後にある「ベストプラクティスを理解したい」というフェーズ全体を経験しています。それとも、これは完全に間違った方法ですか?コントローラーは実際に異なる構造にする必要がありますか?

4

2 に答える 2

2

そもそも、MVCの実装をどのように扱っているかが本当に気に入っています。ビューがコントローラー内で管理される、レールのようなパロディーはありません。

これがあなたの問題の根源だと私が思うものです:あなたはまだ「ダムビュー」アプローチを使用しています。

ビューは「テンプレート」の同義語ではありません。代わりに、複数のテンプレートを処理するための知識と能力を備えた完全なオブジェクトである必要があります。また、MVCに着想を得たほとんどのデザインパターンでは、ビューインスタンスはモデルレイヤーから情報を要求できます。

コードでは、問題はビューのファクトリ(メソッド)にまでさかのぼることができます。ファクトリ$load->view()は、コントローラが送信するものだけを取得します。代わりに、コントローラーはビューの名前のみを変更し、ビューの状態を変更する何かを送信する必要があります。

最善の解決策は、本格的なビューの実装を作成することです。ビュー自体がモデルレイヤーからのデータを要求し、受け取ったデータに基づいて、使用するテンプレートとモデルレイヤーからの追加情報を必要とするかどうかを決定できるようにします。

于 2012-07-22T14:35:44.307 に答える
1

後者のアプローチでは、あなたはある程度正しい方向に進んでいると思います。ただし、ブートストラップでアクションの呼び出しをハードコーディングしないでください。ブートストラップはURLを解釈し、のような関数を使用してアクションメソッドを動的に呼び出す必要がありますcall_user_func_array

また、ビューのレンダリングはアクションコードに任せて、アクションロジックが自給自足で柔軟になるようにすることをお勧めします。これにより、アクションが入力の正しさを分析し、エラーまたはビューを適切にレンダリングできるようになります。また、コントローラーにメソッド'deleteItem'がありますが、これは実際にはモデルの作業である必要があります。おそらく、MVCについてもう少し読んで、既存のフレームワークを使用して概念をよりよく理解してから、独自のフレームワークを実装する必要があります(そのためのYiiフレームワークをお勧めします)。

これは、ロジックを優れたMVCフレームワークに実装する方法の例です。

class ListController extends BaseController
{
    public function CreateAction($title){
        if(ctype_alnum($title))
        {
            $list = new List();
            $list->Title = $title;
            if($list->insert())
            {
                $this->render_view('list/create_successful');
            }
            else
            {
                $this->render_view('list/create_failed');
            }
        }
        else
        {
            $this->render_view('list/invalid_title');
        }
    }

    public function DeleteAction($id){
        $list = List::model()->getById($id);

        if($list == null)
        {
            $this->render_view('list/errors/list_not_found');
        }
        elseif($list->delete())
        {
            $this->render_view('list/delete_successful');
        }
        else
        {
            $this->render_view('list/delete_failed');
        }
    }
}

これは、独自のMVCフレームワークを作成する方法に関する優れたチュートリアルです。

于 2012-07-22T09:23:04.210 に答える