Zend Framework:设置装饰器和标签 - 应该在视图还是表单类中完成?

时间:2010-11-16 00:40:44

标签: php zend-framework zend-form zend-decorators

我注意到许多(大多数?)人在使用Zend Framework时会在Form类本身中添加装饰器和标签。

class User_Form_Add extends Zend_Form
{
    public function init()
    {
        parent::init();
        $username = new Zend_Form_Element_Text('username');
        $username->setLabel('Username:')
                 ->setRequired(true)
                 ->addFilter('StringTrim')
                 ->addValidator('StringLength', $breakChainOnFailure = false, $options = array(1, 30))
                 ->setDecorators(array(
                     'ViewHelper',
                     array('Description', array('tag' => 'p', 'class' => 'description')),
                     array('Label',       array('requiredPrefix'      => '<span class="asterisk">*</span>&nbsp;', 'escape' => false)),
                     array('HtmlTag',     array('tag' => 'p', 'class' => 'element'))
                 ));
    }
}

但这肯定不是好习惯吗?我原以为装饰器和标签是MVC应用程序中视图层的一部分。当我查看这个表单类时,它看起来“很复杂”了应该在视图层中的各种标记,标记和文本。

这种方法意味着如果你需要摆弄表单的标记,你需要使用表单类 viewcript。

我不喜欢这个概念,因此在渲染表单时将表单和装饰器分离为实际的视图脚本。我希望将我的申请中存在的这些相互矛盾的“问题”分开。

class User_Form_Add extends Zend_Form
{
    public function init()
    {
        parent::init();
        $username = new Zend_Form_Element_Text('username');
        $username->setRequired(true)
                 ->addFilter('StringTrim')
                 ->addValidator('StringLength', $breakChainOnFailure = false, $options = array(1, 30));
    }
}

// add.phtml:

$this->form->username->setLabel('Username:');
$this->form->username->setDecorators(array(
    'ViewHelper',
    array('Description', array('tag' => 'p', 'class' => 'description')),
    array('Label',       array('requiredPrefix'      => '<span class="asterisk">*</span>&nbsp;', 'escape' => false)),
    array('HtmlTag',     array('tag' => 'p', 'class' => 'element'))
));

echo $this->form->render();

这使表单类变得干净,与模型类非常相似 - 这就是我对表单类的理解;它包含过滤器,验证器等,它们都与业务逻辑相关。

如果您按照这种方法进行操作,则可以更轻松地将表单与模型集成,以便您可以直接从模型中重用/访问表单验证器和过滤器 - 而无需创建装饰器和不明原因的开销

http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html

至于保持您的视图脚本DRY,这样您就不会在多个视图中重复相同的标签和装饰器(即,当您需要多次渲染相同的表单,但在不同的视图脚本中)时,我找到了你可以使用ViewScript装饰器将表单的可重用部分分开,以保持DRY。

编辑:同样,我们也可以使用适合我们项目的默认装饰器覆盖默认装饰器,以避免首先声明装饰器。

所以我的实际问题是:

为什么没有其他人使用这样的表格?你对这种方法有什么缺点?

如果我可以在视图层中轻松添加装饰器和表单标签,为什么要在表单类中创建装饰器和表单标签?

我不明白为什么我看到的Zend_Form的几乎所有用法都包括在表单类本身中添加装饰器/标签。

4 个答案:

答案 0 :(得分:1)

  

为什么没有其他人使用这样的表格?

我从没想过。非常好的方法。

答案 1 :(得分:1)

回答你的问题,为什么你没有看到人们这样做是因为这根本不是好习惯。表单应该将您的整个表单逻辑基本上封装为一个模块/小部件...您刚刚完成的是将表单拆分到现在您需要担心视图中的标签。这应该都是你的形式,这就是你可以设置标签,装饰等等的所有形式。

答案 2 :(得分:0)

我通常在项目的自定义库或视图助手中的类中声明我的装饰器,然后我可以在每个表单上调用它,并且仍然在一个位置放置所有装饰器以减少所需的代码量对他们来说。

答案 3 :(得分:0)

我认为“其他人不使用这种形式的主要原因”是因为,在大多数情况下,网站只会使用一个或两个“默认”装饰器。如果您要以相同的方式装饰输入90%(可能更少)的时间,为什么还要在每个视图脚本中声明它?

像gokujou的回答一样,我也会在我的库中创建一个自定义装饰器类。见Creating Custom Form Markup Using Zend_Form_Decorator

我确实喜欢你的方法,但我认为它最适合你偏离标准装饰器的情况。如果我大部分时间都使用相同的装饰器,我不想在我的视图脚本中声明它。