首页 > 解决方案 > 使用来自控制器的参数来操作 zend 表单是不是一个坏主意?

问题描述

我目前正在为我的项目创建表单,并且已经在字段集上浪费了时间。首先,我不得不发现你不能在字段集中定义过滤器和验证器,然后在无数次尝试在表单本身中修复它之后,我放弃了它。在混合了字段集表单元素和表单元素之后,我认为它对于我拥有的简单表单来说太复杂了。

所以现在我想我会创建一个通用的 Form 类并将参数从控制器传递给它,以便只创建我需要的元素。这是一个坏主意吗?如果是,为什么?

像这样的东西:

控制器:

$include_title = true
$screening_form->setData($include_title);

形式

public function __construct($include_title)
{
    if ($include_title)
    {
        $this->add([
           'type' => 'text',
           'name' => 'title',
           'options' => [
                'label' => 'text',
                'placeholder' => 'Test',
            ],
        ]);
    }
}

标签: zend-formzend-framework3

解决方案


我建议为不同的上下文保留不同的表单,不要为整个应用程序提供一个大的表单类。根据通过 setData() 传入的数据更改表单外观非常困难,并且可能是导致您的字段集和验证出现问题的原因

如果您想拥有适用于不同上下文的“通用”表单 - 我可能会这样实现它:

<?php
namespace ConferenceTools\Attendance\Form;

use Zend\Form\Element\DateTime;
use Zend\Form\Element\Submit;
use Zend\Form\Form;

class DateTimeForm extends Form
{
    public function init()
    {
        $this->add([
            'type' => DateTime::class,
            'name' => 'datetime',
            'options' => [
                'label' => $this->getOption('fieldLabel'),
            ],
            'attributes' => [
                'class'=> 'datetimepicker-input',
                'id' => "dtpicker",
                'data-toggle' => "datetimepicker",
                'data-target' => "#dtpicker",
                'autocomplete' => 'off',
            ],
        ]);
    }
}

这是此项目中使用的通用日期时间表单:https ://github.com/conferencetools/attendance-module/blob/master/src/Form/DateTimeForm.php

与表单的不同之处在于$this->getOption('fieldLabel')调用,这是将选项传递到表单中的一种比使用构造函数更好的方法。它还在 init 方法而不是构造函数中构建表单,这对于使用选项字段和任何自定义表单元素很重要,这些元素在类完全构建之前不可用。

为了使其正常工作,您需要从标准服务定位器 FormPluginManager(服务名称:'Zend\Form\FormElementManager')中检索它。您可以将其注入工厂的控制器中,然后按如下方式使用它:

// in controller method
$form = $this->formElementManager->get(FormName::class, ['fieldLabel' => 'Arrival time']);

这不是我在上面链接的项目中的做法;我没有将 formElementManager 注入到每个需要它的控制器中,而是创建了一个控制器插件,使它在每个控制器中都可用。(代码相同,只是在一个插件中)


推荐阅读