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 的实现。没有任何类似 rails 的模仿,其中视图是在控制器内部管理的。

我认为这是您问题的根源:您仍在使用“愚蠢的观点”方法。

视图不应该是“模板”的同义词。相反,它应该是一个完整的对象,它具有处理多个模板的知识和能力。此外,在大多数受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 回答