如何在Zend Framework 3中注册自定义表单视图助手

3

我正在将一个继承自Zend Framework 2的应用程序迁移到Zend Framework 3,并遇到了一些问题,即注册我的自定义表单视图助手。当应用程序使用版本2时,这些助手有效,并且主要用于添加可访问性标记属性。例如,这是一个自定义FormText.php辅助程序。

<?php

namespace Application\Form\View\Helper;

use Zend\Form\ElementInterface;
use Zend\Form\View\Helper\FormInput;

class FormText extends FormInput
{
    /**
     * Attributes valid for the input tag type="text"
     *
     * @var array
     */
    protected $validTagAttributes = array(
        'name'           => true,
        'autocomplete'   => true,
        'autofocus'      => true,
        'dirname'        => true,
        'disabled'       => true,
        'form'           => true,
        'list'           => true,
        'maxlength'      => true,
        'pattern'        => true,
        'placeholder'    => true,
        'readonly'       => true,
        'required'       => true,
        'size'           => true,
        'type'           => true,
        'value'          => true,
        'aria-hidden'   => true,
        'aria-invalid'   => true,
        'aria-describedby' => true,
        'aria-label' => true,
    );

    /**
     * Determine input type to use
     *
     * @param  ElementInterface $element
     * @return string
     */
    protected function getType(ElementInterface $element)
    {
        return 'text';
    }
}

在我的应用程序的第二个版本中,助手是在Module.php中注册的(不确定为什么不是在module.config.php中),使用以下方法(只展示了一个助手以保持简洁):
public function getViewHelperConfig()
{
    return array(
        'invokables' => array(
            // Form helpers
            'FormText' => 'Application\Form\View\Helper\FormText',

        ),
    );
}

在我尝试使用ZF3版本的应用程序中,我希望在module.config.php文件的返回语句中使用以下数组元素:
'view_helpers' => [
    'factories' => [
        View\Helper\Cdn::class => View\Helper\CdnFactory::class,
        Form\View\Helper\FormText::class => InvokableFactory::class,
    ],
    'aliases' => [
        'cdn' => View\Helper\Cdn::class,
        'FormText' => Form\View\Helper\FormText::class,
    ],

],

这对于表单视图助手来说是不起作用的,尽管“cdn”助手已经正确地注册并正常工作。表单视图助手不需要任何注入依赖项,因此我没有使用自定义工厂类。在application.config.php中列出了'Zend/Form'模块,并知道标准Zend表单视图助手正在工作。我已经无数次尝试了上面代码的许多变体,尝试使用SO问题的代码示例来注册助手,但所有问题似乎都与普通视图助手有关,而不是表单视图助手。如果您有任何建议,我将非常感激。谢谢。

FormText自定义帮助程序的路径在哪里? - Dolly Aswin
嗨,多莉, 路径是'/module/Application/src/Form/View/Helper/FormText.php'。 谢谢。 - Fergal Andrews
你是否在 Module.php 中删除了代码,然后在视图中使用 $this->FormText() 调用 FormText - Dolly Aswin
@Dolly 是的,它只是使用标准的表单视图助手。 - Fergal Andrews
1个回答

3
从我所在公司的一个活跃项目中举个例子。我们还使用了自己编写的一些默认ZF3表单ViewHelpers,以便与前端框架进行交互。主题名称是“Alpha”(我想是这样的;-))
我们使用以下内容:
'view_helpers' => [
    // other stuff
    'invokables' => [
        'Zend\Form\View\Helper\FormCollection' => AlphaCollection::class,
        'Zend\Form\View\Helper\Form' => AlphaForm::class,
        'Zend\Form\View\Helper\FormRow' => AlphaRow::class,
        'Zend\Form\View\Helper\FormSelect' => AlphaSelect::class,
    ],
],

视图助手本身:

// Namespace + use statements
class AlphaCollection extends FormCollection
{
    public function __construct()
    {
        parent::setWrapper('<div class="alpha-form-collection">%2$s%1$s%3$s</div>');
    }

    /**
     * @param \Zend\Form\ElementInterface $element
     * @param null $labelPosition
     * @return string
     */
    public function render(ElementInterface $element, $labelPosition = null)
    {
        $markup = parent::render($element, $labelPosition);

        $classes = 'input-field col s12 alpha-fieldset';

        if($element instanceof Collection)
        {
            $classes .= ' alpha-fieldset-collection';
        }

        $prepend = '<div class="' . $classes . '">';
        $append = '</div>';

        return $prepend . $markup . $append;
    }
}

因此,实质上,我们不是创造自己的ViewHelpers,而是改变Zend Framework 3提供的ViewHelpers。因为我们只是“更新”现有的ViewHelpers,所以我们不需要创建新的工厂(没有额外的要求)。
Zend Framework已经注册了具有可调用名称的ViewHelpers(因此您可以执行$this->formRow(...)或$this->formSelect(...))。我们只是“劫持”它们的配置并用我们自己的类替换所需的类。这样,当我们完全生成一个表单(form($form) ?>),ZF会为我们完成所有工作。
在.phtml中的实现:
<!-- Internally uses the invokables we've modified, so this is all we need to do :) -->
<?= $this->form($form) ?>

为了使配置更具未来性,我认为您可以用FQCN替换字符串invokable,现在可以这样做(尚未测试)。


谢谢rkeet, 这是一个有趣的方法。我会尝试一下。 - Fergal Andrews
你的解决方案对我来说非常有效,rkeet。非常感谢你。 - Fergal Andrews
不客气。如果将来需要自定义的ViewHelper(而不是修改后的),请看这里:https://zendframework.github.io/zend-view/helpers/advanced-usage/ - 提供了一些示例以便于理解。在底部还有将新的ViewHelper注入渲染器的说明,使其可以通过自定义调用(例如 <?= $this->specialViewHelper($options) ?>)使用。但那是下一步的事情;-) - rkeet
我会看一下,谢谢你rkeet。再次感谢。 - Fergal Andrews

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接