我目前正在使用Zend_Form构建我自己的Form元素集,并希望我的自定义表单中的所有元素都能够使用我的自定义装饰器
所以我创建了一个这样的自定义表单:
<?php
class Nuke_Form extends Zend_Form
{
public function __construct($options = null)
{
$this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');
parent::__construct($options);
}
}
为了完整起见,这是我的装饰者
<?php
class Nuke_Form_Decorator_TwitterBootstrap_ControlGroup extends Zend_Form_Decorator_Abstract
{
public function render($content)
{
$class = $this->getOption('class') ?: "control-group";
$element = $this->getElement();
$errors = $element->getMessages();
if (!empty($errors)) {
$class .= " error";
}
$output = '<div class="' . $class . '">' . $content . '</div>';
return $output;
}
}
以及我在控制器中创建的具体表单实现
class App_Form_Index_Test extends Nuke_Form
{
public function init()
{
parent::init();
$this->addAttribs(array('class' => 'form-horizontal'));
$username = new Nuke_Form_Element_Text('username');
$username->setLabel("Gebruikersnaam")
->setDescription("This is a description")
->setRequired(true)
->addValidator('NotEmpty', true)
->addValidator('int');
$submit = new Zend_Form_Element_Submit('submit');
$this->addElements(array($username, $submit));
}
}
但由于某种原因,Elements无法找到装饰器并输出以下异常:
Message: Plugin by name 'ControlGroup' was not found in the registry; used paths: Zend_Form_Decorator_: Zend/Form/Decorator/
分析异常我看到我的插件路径没有添加,即使我已经在Nuke_Form类中使用addElementPrefixPath()显式添加了它。
奇怪的是,当我将PluginPath单独添加到每个自定义元素时,它可以完美地运行,如下所示。
<?php
class Nuke_Form_Element_Text extends Zend_Form_Element_Text
{
public function init()
{
$this->addPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');
$this->addDecorators(array(
array('ViewHelper', array(
'helper' => 'formText'
)),
array('Errors'),
array('Description', array(
'placement' => Zend_Form_Decorator_Abstract::APPEND,
'class' => 'help-block'
)),
array(array('controls' => 'HtmlTag'), array(
'tag' => 'div',
'class' => 'controls',
)),
array('Label', array(
'class' => 'control-label',
'requiredSuffix' => ' *',
'placement' => Zend_Form_Decorator_Abstract::PREPEND
)),
array('ControlGroup')
));
}
}
我正在使用最新版本的Zend Framework(v1.11.11)。
经过一些研究后我发现addElementPrefixPath()会在调用时添加所有添加的表单元素的路径,我想这就是为什么在Nuke_Form构造函数中调用它时它不起作用,因为当时没有元素有已被添加。但是我们怎么应该使用这种方法呢?我在网上发现了几个在构造函数中成功调用它的例子。我很困惑或忽略了什么。
答案 0 :(得分:2)
尝试在构造函数中传递它:
$options = array('elementPrefixPath' => 'Nuke/Form/Decorator/TwitterBootstrap/');
或者可能把它放在init()中:
public function __construct($options = null)
{
parent::__construct($options);
}
public function init() {
$this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap_', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');
}
}
我认为在init()中调用它会效果最好。并且不要在这里打电话给parent::init();
,它只是Zend_Form中的一个空函数,没有什么可以覆盖。
我使用了除自定义元素之外的所有代码,我在inti()中设置了elementPrefixPath,并使用addDecorator()对正常的Zend_Form_Element调用了ControlGroup Decorator,这是输出:
<form enctype="application/x-www-form-urlencoded" class="form-horizontal" method="post" action=""><dl class="zend_form">
<div class="control-group"><dt id="username-label"><label for="username" class="required">Gebruikersnaam</label></dt>
<dd id="username-element">
<input type="text" name="username" id="username" value="" />
<p class="description">This is a description</p></dd></div>
<dt id="submit-label"> </dt><dd id="submit-element">
<input type="submit" name="submit" id="submit" value="submit" /></dd></dl></form>
我做的唯一更改是在前缀中添加一个尾随的 _ 。
<?php
class Application_Form_NukeForm extends Zend_Form
{
public function __construct($options = null)
{
parent::__construct($options);
}
public function init(){
$this->addElementPrefixPath('Jgs_Decorator_', '/Jgs/Decorator/', 'decorator');
}
}
当然我用自己的路径......
<?php
class Application_Form_Test extends Application_Form_NukeForm
{
public function init()
{
parent::init();
$this->addAttribs(array('class' => 'form-horizontal'));
$username = new Zend_Form_Element_Text('username');
$username->setLabel("Gebruikersnaam")
->setDescription("This is a description")
->setRequired(true)
->addValidator('NotEmpty', true)
->addValidator('int')
->addDecorator('ControlGroup');
$submit = new Zend_Form_Element_Submit('submit');
$this->addElements(array($username, $submit));
}
}
我只重命名装饰器以适应我的路径
<?php
class Jgs_Decorator_ControlGroup extends Zend_Form_Decorator_Abstract
{
public function render($content)
{
$class = $this->getOption('class') ?: "control-group";
$element = $this->getElement();
$errors = $element->getMessages();
if (!empty($errors)) {
$class .= " error";
}
$output = '<div class="' . $class . '">' . $content . '</div>';
return $output;
}
}
我认为你的问题在其他地方...... 我也让__constructor工作,我不得不调整参数以获得正确的选项:
<?php
class Application_Form_NukeForm extends Zend_Form {
public function __construct($options = array('elementPrefixPath' => array(
'prefix' => 'Jgs_',
'path' => '/Jgs/',
'type' => 'decorator'
))) {
parent::__construct($options);
}
我真的希望这会有所帮助:)
答案 1 :(得分:0)
在class Nuke_Form_Element_Text
中如果你调用setDecorators()而不是addDecorators(),你可能会更好,因为它看起来好像你要替换所有的默认装饰器。
你也可以添加{ {1}}