Zend Framework:设置装饰器和标签 - 应该在视图还是表单类中完成?
我注意到许多(大多数?)人在使用 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> ', 'escape' => false)),
array('HtmlTag', array('tag' => 'p', 'class' => 'element'))
));
}
}
但这肯定不是一个好的做法吗?我本以为装饰器和标签是 MVC 应用程序中视图层的一部分。当我查看这个表单类时,它看起来被各种应该位于视图层中的标记、标签和文本“污染”了。
这种方法意味着,如果您需要修改表单的标记,则需要使用表单类和视图脚本。
我不喜欢这个概念,因此在渲染表单时将表单和装饰器分离到实际的视图脚本中。我想将我的应用程序的这些相互冲突的“问题”分开。
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> ', '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
至于保持视图脚本干燥,这样您就不会在多个视图中重复相同的标签和装饰器(即当您需要渲染相同的表单时)多次,但在不同的视图脚本中),我发现您可以使用 ViewScript 装饰器将表单的可重用部分分开,以保持干燥。
编辑:同样,我们还可以使用适合我们项目的装饰器覆盖默认装饰器,以避免首先不必要地声明装饰器。
所以我的实际问题是:
为什么没有其他人像这样使用他们的表单?您认为这种方法有哪些缺点?
如果我可以轻松地将装饰器和表单标签添加到视图层中,为什么要在表单类中创建它们呢?
我不明白为什么我看到的几乎所有 Zend_Form
用法都包括在表单类本身中添加装饰器/标签。
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> ', '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> ', '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 (i.e. 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我从来没有想过。非常好的方法。
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 typically declare my decorators and such in a class in a custom library for the project or in a view helper that I can then call in on each form and still have all the decorators in one location to reduce the amount of code needed for them.
我认为“其他人不这样使用他们的表单”的主要原因是,在大多数情况下,网站只会使用一两个“默认”装饰器。如果您打算在 90%(也许更少)的时间内以相同的方式装饰输入,为什么还要在每个视图脚本中声明它呢?
就像 gokujou 的答案一样,我也将在我的库中创建一个自定义装饰器类。请参阅 使用 Zend_Form_Decorator 创建自定义表单标记
我很喜欢你的方法,但我认为它最适合您与标准装饰器有偏差的情况。如果我大部分时间都使用相同的装饰器,我不想在我的视图脚本中声明它。
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.