11

我目前的实现:

class SomeController extends AppController
{
    function someaction()
    {   
        $d['text'] = "ahoy!";
        $this->render("someactionView", $d);
    }
}

并在AppController

function render($file, $data = "")
{
    require "views/" . $file . ".php";
}

并且$data将在视图文件中可用。这是一个正确的实现吗?这个实现有什么谬误吗?

4

3 回答 3

13

并且$data将在视图文件中可用。这是一个正确的实现吗?这个实现有什么谬误吗?

基本上你确实像大多数框架一样实现它。这样做有几个问题:

  • 控制器接受输入并发送输出(这违反了单一职责原则)
  • 视图与 HTML 紧密耦合。因此,您不能将相同的视图重复用于其他内容,例如 XML、JSON。
  • 如果你这样做require "views/" . $file . ".php";-render()你再次紧密结合它。如果更改视图的位置怎么办?然后你将不得不稍微重写你的方法。这种方法只会扼杀重用能力。

刷新您的基础知识:

控制器(也称为编辑器)

仅用于单一目的。它改变了模型状态——也就是说,它应该接受来自$_POST, $_GET, $_FILES,的输入$_COOKIE。在控制器中,仅应进行变量分配,仅此而已

class Controller
{
   public function indexAction()
   {
        $this->view->setVar('age', $this->request->getPostParam('age'));
        $this->view->setVar('user', $this->request->getPostParam('user'));
        //...
   }
}

看法

视图可以直接访问模型。为了使视图更具可重用性和可维护性,您最好将所需的东西作为函数参数(或通过设置器)传递

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

      return ob_get_clean();
   }
}

应该如何初始化视图以及如何将变量传递给它?

首先 - 一个视图应该在 MVC-triad 之外实例化。由于控制器写入视图或模型 - 您可以通过控制器将变量传递给视图。

$model = new Model();
$view = new View($model);

$controller = new Controller($view);

// This will assign variables to view
$controller->indexAction();

echo $view->render();

注意:在现实世界的场景中,模型不是一个类,而是抽象层。我称之为Model演示目的。

于 2013-09-24T14:08:21.680 回答
3

IMO 该render()方法属于视图而不属于控制器。代码应如下所示:

控制器:

class SomeController extends AppController
{
    function someaction()
    {   
        $d['text'] = "ahoy!";
        $view = new SomeActionView();
        $view->assign('data', $d);
        echo $view->render();
    }
}

查看基类:

class View
{

    protected $data;

    function render($template) {
        ob_start();
        // you can access $this->data in template
        require "views/" . $template . ".php";
        $str = ob_get_contents();
        ob_end_clean();
        return $str;
    }


    function assign($key, $val) {
        $this->data[$key] = $val;
    }
}

扩展视图类

class SomeActionView extends View
{

    public function render($template = 'someActionTemplate') {
        return parent::render($template);
    }

}
于 2013-09-22T23:38:03.523 回答
2

这是一个正确的实现吗?这个实现有什么谬误吗?

简短的回答:没有和几个。

首先,你所拥有的没有一个观点。这只是一个愚蠢的php 模板。MVC 中的视图是实例,包含应用程序的 UI 逻辑。他们从模型层提取信息,并根据收到的信息创建响应。该响应可以是简单的文本、JSON 文档、由多个模板组合而成的 HTML 页面,或者只是一个 HTTP 标头。

至于控制器,它唯一的任务是改变模型层的状态和(在极少数情况下)当前视图。控制器初始化视图也不填充模板。

于 2013-09-23T00:56:19.373 回答