Zend framework Zend_形式:addlementprefixpath与addPrefixPath

Zend framework Zend_形式:addlementprefixpath与addPrefixPath,zend-framework,zend-form,zend-decorators,Zend Framework,Zend Form,Zend Decorators,我目前正在使用Zend_表单构建自己的表单元素集,希望自定义表单中的所有元素都能够使用自定义装饰器 因此,我创建了一个自定义表单,如下所示: <?php class Nuke_Form extends Zend_Form { public function __construct($options = null) { $this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap',

我目前正在使用Zend_表单构建自己的表单元素集,希望自定义表单中的所有元素都能够使用自定义装饰器

因此,我创建了一个自定义表单,如下所示:

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

    }

}
但由于某些原因,元素无法找到装饰器并输出以下异常:

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

尝试在构造函数中传递它:
$options=array('elementPrefixPath'=>'Nuke/Form/Decorator/TwitterBootstrap/')

或者把它放在init()中: 我认为在init()中调用它最有效。而且不必费心调用
parent::init()
这确实有效
我使用了除custom元素之外的所有代码,我在inti()中设置了elementPrefixPath,并使用addDecorator()调用了ControlGroup Decorator,与普通Zend_Form_元素相对应,这是输出:

<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">&#160;</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');
    }

}

类Nuke\u Form\u Element\u Text
中,如果调用setDecorators()而不是addDecorators(),可能会更好,因为看起来好像您正在替换所有默认的decorators。
您也可以只添加
$this->loadDefaultdecorisdisabled()

这也不起作用,我开始认为这可能是一个bug,看看Zend_Form::addElementPrefixPaths()它只是在所有元素上循环并设置prefixPath,问题是。。。在Zend_表单构造函数或init方法中,尚未定义任何元素!好的,正如您所观察到的,
$form->addElementPrefixPath()
似乎将前缀路径添加到了迄今为止添加的所有元素中,这意味着它不能按您希望的方式使用:在添加元素之前配置表单,然后添加依赖于该配置的元素。另一方面,在添加了所有元素之后,您可以在过程的稍后调用
addlementprefixpath()
,甚至可以覆盖表单的
render()
方法并在其中添加前缀路径。@David Weinraub-我成功地实现了这一点,更新的答案。@RockyFord:仔细查看
Zend_Form::addElementPrefixPath()
的代码、
Zend_Form::addElementPrefixPath()
的代码、您更新的答案以及我之前的评论,我得出结论,这两个函数都很奇怪(为什么复数函数不简单地在一个列表上迭代,调用单数函数?)我上面的评论是垃圾。我可能很快就会删除我上面的评论——还有这一条。很高兴你找到了一种似乎有效的方法
public function __construct($options = null)
{
    parent::__construct($options);

}
public function init() {
    $this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap_', 'Nuke/Form/Decorator/TwitterBootstrap/', '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">&#160;</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;
    }

}
<?php

class Application_Form_NukeForm extends Zend_Form {

    public function __construct($options = array('elementPrefixPath' => array(
            'prefix' => 'Jgs_',
            'path' => '/Jgs/',
            'type' => 'decorator'
    ))) {

        parent::__construct($options);
    }