Zend_Form在Model View Controller范例中的适用范围

时间:2010-10-21 12:40:06

标签: model-view-controller zend-framework zend-form

Zend Framework主要用于MVC。其中一个非常有用的组件是Zend_Form

找到Zend_Form的位置有点麻烦。它是视图,模型或控制器的一部分,我应该赋予它哪些职责。

问题是,Zend_Form做了两件事:装饰并渲染表单并验证它。第一个是真实的视图任务,第二个是真正的模型任务。

现在最常见的用途似乎是让表单只与控制器交互,有效地将两个任务(渲染和验证)放到视图/控制器中。

Matthew Weier O'Phinney给出的另一个选项是将表单附加到模型,并在控制器中添加后面的视图选项。

所以,我很怀疑。我应该在MVC模式中放置Zend_Form以及如何使用它?

编辑目前为止的答案很好,谢谢!我将在它到期前一两个小时给予赏金,所以如果你有更多的想法,请给出答案!

3 个答案:

答案 0 :(得分:5)

Zend_Form可以在不同的点上查看。它根本不能被视为一层MVC模式的一部分。

首先,Zend_Form使用装饰器和视图助手来渲染表单,此时它是视图层的一部分。 然后,Zend_Form执行模型作业过滤的一部分并验证内容。

我们知道Controller层从视图渲染输入并将其传递给模型。实际上,控制器层决定从模型层加载哪个资源,然后执行更正调用。

当您从控制器层调用Zend_Form时,您可以考虑调用一个模型资源来执行valitation和过滤操作,并确定这是否是有效输入。例如:

public function newAction()
{
    $form = $this->getForm();

    if($this->getRequest()->isPost()) 
    {
        $formData = $this->_request->getPost();

        if($form->isValid($formData))
        {
            $Model = $this->getModel();
            $id = $Model->insert($form->getValues());
        }
    }

    $this->view->form = $form;
}

将表单绑定到模型可以被认为是一个很好的实践,因为当您执行过滤和验证操作时,您处于模型层。所以,正如马修提出的那样:

class Model_DbTable_Users extends Zend_Db_Table
{
    protected $_name = 'users';  
    protected $_form;

    public function getForm()
    {
        if(!$this->_form)
            $this->_form = new Form_User();
        return $this->_form;
    }

    public function add($data)
    {
        $form = $this->getForm();
        if(!$form->isValid($data)) return false;

        if($form->getValue('id'))
        {
            $id = (int) $form->getValue('id');
            $this->update($form->getValues(), 'id =' . $id);
        }   
        else
        {
            $id = $this->insert($form->getValues());
        }
        return $id;
    }
}

从标准目录结构中我们可以看到Forms不在模型文件夹中,也不在视图文件夹中,因为Zend_Form是一个将许多资源和层绑定在一起的特定类。如果您查看Matthews帖子,您会发现这正是在视图脚本上设置操作URL并且表单与模型绑定时所说的内容。

最后,您可以分析您的背景并选择其中一种方法。

目前,我的选择是将表单与模型联系起来。看起来不错!对我来说很有意义。

答案 1 :(得分:2)

IMO,Zend_Form旨在戴上多个帽子。事实上,它是视图和模型之间的桥梁,带有来自控制器的巨大支撑梁。

不要将表单分配给模型,而是考虑将模型分配给表单。

在Model层中,您可以拥有一个getFormInputs方法,该方法可以返回输入数据所需的Elements。该模型并不关心将使用它的形式,它只是让任何想要它的人都可以使用它。

现在在表单层中,创建一个setupInputs方法,该方法将通过一组模型循环以获取所有输入。如果只有一个模型,请将输入添加到表单中。如果有多个模型,请创建子表单。

您的控制器将启动表单并将值传递回模型(请参阅Keyne的newAction方法)

答案 2 :(得分:1)

Zend_Form经常感觉像是一个奇怪的人。我想每个人的里程都各不相同。

最近,我的大多数管理界面都非常拖放AJAX-y,并且它们需要大量的html和javascript - 实际的表单元素很稀疏。因此,我选择避开Zend_Form的许多功能,并将其用作具有过滤功能的花式视图助手。我的所有验证都是在模型中的单独层上完成的。

我认为O'Phinney的想法也很有意义。在这里,他选择将表单视为域对象的一个​​组件 - 他可以在其中添加业务逻辑。这听起来很好,只要你小心保持表单的所有视图逻辑分开。正如他所指出的,它是关于使语义有意义的。不一定是硬性规定。