简体   繁体   中英

Zend Framework: Setting decorators and labels - should this be done in the view or the form class?

I notice that many (most?) people when working with Zend Framework add decorators and labels in the Form class itself.

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'))
                 ));
    }
}

But surely this is not good practice? I would have thought that decorators and labels are part of the view layer in an MVC application. When I look at this form class, it looks "poluted" with all sorts of markup, tags and text that should be in the view layer.

This approach means that if you need to fiddle with the markup of your form, you need to work with both the form class and the viewscript.

I don't like that concept, and so have been separating the forms and decorators into the actual view scripts when I am rendering the forms. I want to keep these conflicting "concerns" of my application separate.

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();

This leaves the form class clean, and quite analogous to a model class - that's how I percieve the form class to be; It contains filters, validators etc, which are all business-logic related.

If you then follow this approach, it makes it easier to integrate your forms with your models, such that you can reuse/access the form validators and filters directly from within your models - without the overhead of having created decorators and whatnot unnessesarily.

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

As far as keeping your view scripts DRY, such that you're not repeating the same labels and decorators in multiple views (ie when you need to render the same form multiple times, but in different view scripts), I find you can separate re-usable parts of a form out using the ViewScript decorator to keep things DRY.

EDIT : As well, we can also override the default decorators with ones appropriate to our project to avoid having to unnessesarily declare decorators in the first place.

So my actual question is this:

Why isn't anyone else working with their forms like this? What drawbacks do you see for this approach?

Why should decorators and form labels be created in the form class, if I can just as easily add them in the view layer?

I don't get why nearly every usage of Zend_Form I see includes adding decorators/labels in the form class itself.

Why isn't anyone else working with their forms like this?

I never thought of. Very good approach.

To answer your question as to why you don't see people doing this is because this simply is not good practice. A form should encapsulate your entire form logic basically a module/widget...what you have just done is split your form up where you now have to worry about your labels in the view. This should all be in your form that's why you can set the labels, decorators etc.. all in the form.

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

I think the major reason why "anyone else isn't working with their forms like this" is because, for the most part, a site will only use one or two 'default' decorators. If you are going to decorate the inputs the same way 90% (perhaps less) of the time, why bother declaring it in every view script?

Like gokujou's answer, I too will create a custom decorator class in my library. See Creating Custom Form Markup Using Zend_Form_Decorator

I do like your approach, but I think it's most appropriate for instances where you have a deviation from the standard decorator(s). If I'm using the same decorators the majority of time, I don't want to have to bother with declaring it in my view script.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM