使用Zend Framework 2中的FormElement ViewHelper渲染自定义表单元素

Dan*_*l M 3 php zend-form viewhelper zend-framework2

我已经为一个特殊的,复杂的目的创建了一个新的表单元素类(带有附加按钮的文本输入字段,用于打开"搜索向导"弹出窗口).

为了正确呈现这个元素,我还创建了一个表单视图助手.一切正常,到目前为止还不错.

但是,如果我尝试使用FormCollection视图助手渲染表单,则该元素将呈现为基本输入元素.这是因为FormCollection助手依赖的FormElement视图助手使用硬编码的if子句系列将元素的类型映射到特定的表单视图助手.它无法映射我的元素类,因此可以回归FormInput.

即(取自Zend/Form/View/Helper/FormElement.php,第41-49行):

    if ($element instanceof Element\Button) {
        $helper = $renderer->plugin('form_button');
        return $helper($element);
    }

    if ($element instanceof Element\Captcha) {
        $helper = $renderer->plugin('form_captcha');
        return $helper($element);
    }

    ...

    $helper = $renderer->plugin('form_input');
    return $helper($element);
Run Code Online (Sandbox Code Playgroud)

等等.

我有点卡在这里,因为这种架构并没有真正提升可扩展性.

我想到的唯一解决方案(除了手工渲染表单)是扩展FormElement视图助手类,从而创建我自己的CustomFormElement视图助手.但是,由于其复杂性,我将自定义元素放入自己的模块中.所以我必须动态编写这个CustomFormElement助手来添加来自任何模块的自定义元素.我不认为这是推荐的程序.

还有其他解决方案,或者甚至是我的完整方法未经推荐?提前致谢!

mar*_*ini 7

我认为最简单的方法是扩展Zend\Form\View\Helper\FormElement,处理方法中的字段类型,render()并将FormElement注册为应用程序/模块的默认FormElement.假设您有要呈现的自定义TestField:

namespace Application\Form\View\Helper; 

use \Zend\Form\ElementInterface;
use \Zend\Form\View\Helper\FormElement
use \Application\Form\Element\TestField;

class MyFormElement extends FormElement
{
    public function render(ElementInterface $element)
    {
        $renderer = $this->getView();
        if (!method_exists($renderer, 'plugin')) {
            // Bail early if renderer is not pluggable
            return '';
        }

        //your custom fields go here...
        if ($element instanceof TestField) {
            $helper = $renderer->plugin('\Application\Form\View\Helper\FormTestField');
            return $helper($element);
        }

        return parent::render($element);
    }
}
Run Code Online (Sandbox Code Playgroud)

在Application/config/module.config.php中:

'view_helpers' => array(
    'invokables' => array(
         'form_element' => 'Application\Form\View\Helper\MyFormElement',
    )
)
Run Code Online (Sandbox Code Playgroud)