控制器或视图

时间:2014-06-27 13:11:28

标签: php asp.net-mvc laravel

我总是编码控制器,以便他们只需从模型中调用数据,然后将该数据呈现给视图:

class ProjectViewModel
{
    public $User = NULL; // Contains authentication levels etc    
    public $Projects = NULL;
}

class ProjectController
{
    //...

    public function ListProjects()
    {
        $viewModel = new ProjectViewModel();
        $viewModel->User = $this->sessionRepository->GetSession();
        $viewModel->Projects = $this->projectRepository->Projects();
        return View::make( "ViewName", $viewModel );
    }
}

现在在我看来:

<ul>
    <?php foreach( $Model->Projects as $project ) { ?>
        <li>
            <?=$project->Title?>
            <?php
                switch( $Model->User->Authentication->Type )
                {
                    case AuthenticationType::ADMIN:
                        | <button>Edit</button>
                    break;
                }
            ?>
        </li>
    <?php } ?>
</ul>

你在我的做事方式中看到,设计视图的人根据用户的身份验证来决定显示的内容...不要仅仅因为我是如何做到这一点,你可以考虑模型返回项目的属性,说明它们是否可以编辑特定项目...主要思想是有1个布尔值,表明某人是否可以对项目做某事。

我的同事采用了不同的方法,这很有趣,因为他在控制器中定义了一个“按钮”(如果视图人决定显示它,可能存在也可能不存在)应该以不同的方式显示:

class ProjectController
{
    //...

    public function ListProjects()
    {
        $viewModel = new ProjectViewModel();
        $viewModel->User = $this->sessionRepository->GetSession();
        $viewModel->Projects = $this->projectRepository->Projects(); 
        $viewModel->Buttons = array(
           "EditButton" => array(
               "Name" => "Edit button",
               "Show" => ( $viewModel->User == AuthenticationType::ADMIN ) ? TRUE : FALSE
           ),               
           "OpenProjectReportButton" => array(
               "Name" => "Open project report",
               "Show" => ( $viewModel->User == AuthenticationType::ADMIN ) ? TRUE : FALSE
           )
        );
        return View::make( "ViewName", $viewModel );
    }
}

在视图中,他使用已在控制器中预先声明的按钮:

<ul>
    <?php foreach( $Model->Projects as $project ) { ?>
        <li>
            <?=$project->Title?> 
            <?php if( $project[ "EditButton" ][ "Show" ] ) { ?>
                <button><?$project[ "EditButton" ][ "Name" ]?></button>                
            <?php } ?>
        </li>
    <?php } ?>
</ul>

虽然我理解他为什么认为这是一个好主意,但控制器现在正在进行视图的一些工作......事实上,他已经远远地说视图会有按钮..设计师可能不同意......

这也意味着如果视图人想要在其他地方添加另一个按钮,他将不得不要求控制器人员在阵列中给他一个新按钮以获得其他东西......并且在这样做之后,他可能会说,实际上它不是一个按钮,我只是想显示一个图像......

我认为这是错的吗?

概述:

  • 控制器应该从模型中获取数据,并将其推送到视图的视图,以显示它如何显示它... 视图应该使用该数据来决定在视图上显示的方式和内容...(更进一步,如果您担心如果他们点击该按钮会意外显示管理员按钮由视图工程师提供,没关系..用户被带到另一个加载控制器的页面,该控制器坚持实际上,该用户无法访问此页面...)
  • 视图人应该问这样的问题,这个用户可以编辑项目......而不是给我一个可以显示给视图的按钮

如果视图人真的决定了,为了设计目的,我想要显示用户无法使用的按钮...并提供一条消息,说明他为什么不能使用它......我同事的控制器示例提供了一个按钮列表,现在必须忽略,考虑到视图工程师(艺术家/设计师)实际决定,拧紧控制器......我想显示该按钮!

我是对的吗?

编辑::我添加了新标签,因为我知道PHP和C#人的问题解决方法非常不同......我也对asp.net用户的观点感兴趣。

2 个答案:

答案 0 :(得分:1)

适当的MVC分离只是恰当地分离责任:

  • 该模型完成所有工作,您的应用程序可以做的所有事情&#34;是厚模型层的一部分
  • 该视图可视化模型的状态,即您的应用中发生的事情,用户(或其他实体)
  • 控制器主要只响应事件(输入)并指示它们采取适当的操作以在模型中发生某些事情并在必要时刷新视图;它是模型,视图和世界其他地方之间的管道

因此,控制人的业务并不是做与演示有关的任何事情。该视图也不仅仅是单个.php HTML模板。视图可以与模型层一样厚,它的职责是执行生成有用输出所需的任何操作。视图应直接与模型对话,以获取所需的状态信息。几乎所有当前在控制器中的代码都属于视图。

答案 1 :(得分:1)

一些事情,首先要扩展deceze所说的:

  

&#34;几乎所有当前在控制器中的代码   属于视图&#34;

我同意,你的控制器被那些不应该存在的东西搞砸了。您的控制器应如下所示:

class ProjectController
{
    public function ListProjects()
    {
        return View::make("ViewName");
    }
}

数据准备在Laravel的ViewComposers中更好。

在Laravel中,他们有一个名为ViewComposer的构造。它旨在为您的观点准备数据。

您指定一个名为:

的类
class ViewNameComposer {

    public function compose($view){
        $view->model = new ProjectViewModel();
        $view->model->User = $this->sessionRepository->GetSession();
        $view->model->Projects = $this->projectRepository->Projects();
    }
}

然后用视图注册它:

View::composer('ViewName', 'ViewNameComposer');

当呈现该视图时,作曲家会挂钩并准备视图的数据。

真正令人敬畏的是,您可以将ViewComposer与部分视图片段相关联。

这意味着当你使用时说刀片模板引擎和你的页面视图有一个布尔值,决定是否显示一些&#34;其他内容&#34;,如果你保存&#34;其他内容& #34;作为部分视图片段并有条件地包含它

@if($someBool)
    @include ('partials.ViewName.othercontent')
@endif

然后你只能加载partials.ViewName.othercontent需要的数据(来自partials.ViewName.othercontent的ViewComposer)。

我喜欢这种方法,它有助于保持视图更清洁,并消除不应该在控制器中的垃圾。

有关ViewComposers的更多信息,请查看其文档:

http://laravel.com/docs/responses#view-composers