控制器和视图之间的 1:1 关系有什么用途


What purpose does a 1:1 relationship between controller and view serve?

我正在寻找对 MCV 中视图层的更好解释,特别是程序中的流程如何从一个控制器转到另一个视图,重点关注在控制器和视图之间使用 1:1 关系时的模型状态。

在所有示例中,我都看到数据从控制器转发到视图,并且视图不执行任何需要为特定控制器编写特定视图的特定操作。我是否误解了 1:1 关系的口头禅?我找到的最新例子是几天前发布在这里的:https://stackoverflow.com/a/18983927/1681418

class View
{
   public function render($templateFile, array $vars = array())
   {
      ob_start();
      extract($vars);
      require($templateFile);
      return ob_get_clean();
   }
}

我尝试为每个控制器创建特定的视图类,并且我当前有一个视图,该视图在需要时从模型中提取所有数据。从某种意义上说,它很干净,因为我有一个非常定义的模型部分(=控制器)和一个从模型只读的部分(=view)。但是,我有一些缺点尚未找到整洁的解决方案,即:

  • 应在哪里选择模板文件?
  • 视图如何了解模型中的错误?
  • 视图如何了解控制器中成功或不成功的命令/操作?
  • 出现错误时如何更改视图?或者,如何在用户状态更改的情况下正确执行路由。

我在页面上呈现正确的输出没有问题,但我目前的方法感觉是错误的。 **有人得到一个使用领域驱动设计的视图示例,该视图将模型作为层,而不是类?

**

这个答案与我通常发现的非常相似,我不明白这种方法如何使用或需要 1:1 关系。

我主要寻找示例,而不是代码审查,但无论如何,我已经在下面提取了一些代码作为示例。在这里,我通过调度程序调用控制器进行访问控制和路由,然后通过同一调度程序调用视图以再次检查访问权限。视图依次调用不同的表示对象,如果 http 请求,则将数据分配给模板引擎,如果 ajax 请求,则将数据分配给 json。

class Controller
{
    public function login()
    {
        $this->serviceFactory
            ->build('recognition')
            ->authenticate($this->request->username, $this->request->password);
    }
}
class View
{
    public function login()
    {
        /** Prepare server response (i.e. state of the model) */
        $this->presentationObjectFactory
            ->build('serverresponse', true)
            ->setPresentationName('success')
            ->assignData($this->serviceFactory->build('modelLog')->getModelResponse('success'));
        /** Get current visitor information */
        $this->presentationObjectFactory
            ->build('visitor', true)
            ->assignData($this->serviceFactory->build('recognition')->getCurrentVisitor()); 
        return $this->serviceFactory->build('recognition')->getCurrentVisitor()->isLoggedIn() ? 
                    $this->indexAction() : /* Reroute to index of view */
                    $this->display('login.html'); /* Show the login template when unsuccesful login*/
    }
}
class PresentationObject
{
    public function assignData(Collection $visitors)
    {
        $dateformat = new DateFormat();
        $dateTime = new 'Datetime();
        foreach($visitors as $visitor)
        {
            $dateTime->setTimestamp($visitor->timestamp);
            $this->assign_block_vars('visitor', array(
                'ID'                => $visitor->id,
                'USERNAME'          => $visitor->user->Username,
                'IP'                => $visitor->remote_addr,
                'HTTP_USER_AGENT'   => $visitor->http_user_agent,
                'LAST_SEEN_ONLINE'  => ucfirst($dateformat->formatDateDiff($dateTime)),
                'DEVICE'            => $visitor->getDevice(),
                'PLATFORM'          => $visitor->getPlatform(), 
                'BROWSER'           => $visitor->getBrowser(),  
            ));
        }
    }
}

我对 MVC 和领域驱动设计的知识和理解受到用户 tereško 的强烈影响,但我可能误解了这个解释的视图部分的一些东西......

控制器和视图之间的 1:1 关系有什么用途?

如果视图可以应用于多个工作流上下文/控制器/模型,则不需要严格的 1:1 规则。 将视图和控制器分开,即使它们只能一起使用并且可以合并,也是明确职责分离的最佳做法。它还使以后交换和共享视图变得更加容易。

应在哪里选择模板文件?

在您的情况下,您有一个 View 类,因此应该在那里定义它。在某些系统中,模板视图,通常在控制器或配置文件中选择。

视图如何了解模型中的错误? 视图如何了解控制器中成功或不成功的命令/操作?

在某些体系结构中,模型在更新或任何其他操作期间将其问题返回给控制器。 在控制器中,我通常会将任何问题添加到用户消息堆栈中。然后在视图中,我将这些消息输出给用户。

出现错误时如何更改视图?或者,如何在用户状态更改的情况下正确执行路由。

我见过以多种不同的方式处理这个问题。 最可靠的解决方案是让控制器将后续工作流步骤传递到视图。 该视图基本上应尽可能与任何业务逻辑无关。

对于 SO 来说,任何示例代码都太长和复杂。 我会从好的MVC框架教程开始:

  • 拉维尔验证规则
  • 代码点火器表单验证
  • Symfony验证