Zend framework2 使用Zend Framework 2动态生成表单

Zend framework2 使用Zend Framework 2动态生成表单,zend-framework2,zend-form,Zend Framework2,Zend Form,我正在创建ZF2轮询模块。我有很多问题要问。每个问题都有答案,可以是多个答案,也可以是单个答案(收音机或多检查盒)。如何创建一个可以显示给前端的动态表单 这是我尝试过的,但是表单没有正确验证 module\Polls\src\Polls\Form\PollFillingQuestionsForm.php <?php namespace Polls\Form; use Zend\Form\Form; use Polls\Form\Fieldset\PollFil

我正在创建ZF2轮询模块。我有很多问题要问。每个问题都有答案,可以是多个答案,也可以是单个答案(收音机或多检查盒)。如何创建一个可以显示给前端的动态表单

这是我尝试过的,但是表单没有正确验证

module\Polls\src\Polls\Form\PollFillingQuestionsForm.php

  <?php
    namespace Polls\Form;

    use Zend\Form\Form;
    use Polls\Form\Fieldset\PollFillingQuestionAnswerFieldset;
    use Polls\Form\Fieldset\PollFillingQuestionFieldset;

    class PollFillingQuestionsForm extends Form {

    public function __construct($questionsObject) {
        parent::__construct('questionsForm');

        $questionsFieldset = new PollFillingQuestionFieldset('questions');

    //$questionsObject is array of question objects.
        foreach ($questionsObject as $questionObject) {
            $fieldset = new PollFillingQuestionAnswerFieldset($questionObject->id, array(), $questionObject);
                $questionsFieldset->add($fieldset);
            }

            $this->add($questionsFieldset);

            $this->add(array(
                'name' => 'submit',
                'attributes' => array(
                    'type' => 'submit',
                    'value' => 'Submit Poll',
                    'class' => 'btn btn-success',
                ),
            ));
        }
    }
<?php

namespace Polls\Form\Fieldset;

use Polls\Model\QuestionAnswer;
use Zend\Form\Fieldset;
use Zend\Stdlib\Hydrator\ArraySerializable;

class PollFillingQuestionAnswerFieldset extends Fieldset {

public function __construct($name, $options, $questionObject) {
    parent::__construct($name, $options);

    $question = $questionObject;

    $this->setLabel($question->title);

    $type = 'Radio';
    $elementType = 'radio';
    switch ($question->answer_type) {
        case 'many':
            $type = 'MultiCheckbox';
            $elementType = 'checkbox';
            break;
        case 'one':
            $type = 'Radio';
            $elementType = 'radio';
            break;
        default:
            $type = 'Radio';
            $elementType = 'radio';
            break;
    }
    $this->setHydrator(new ArraySerializable())
            ->setObject(new QuestionAnswer());

    $answers = $question->getAnswers();

    $answerValues = array();
    foreach ($answers as $answer) {
        $answerValues[$answer->id] = $answer->title;
    }
    $this->add(array(
        'name' => 'answer',
        'type' => $type,
        'options' => array(
            'type' => $elementType,
            'value_options' => $answerValues,
        ),
    ));
}
}

我以前也这样做过,通过一个干净的工厂策略,您可以将依赖项注入到表单和输入过滤器中。魔力在于你的工厂

首先,在service manager配置中连接以下内容:

'form_elements' => [
    'factories' => [
        DynamicForm::class => DynamicFormFactory::class,
    ],
],

'input_filters' => [
    'factories' => [
        DynamicInputFilter::class => DynamicInputFilterFactory::class,          
    ],
],
第一个任务是把你的模板工厂做好

class DynamicFormFactory implements FactoryInterface, MutableCreationOptionsInterface
{

    /**
     * @var array
     */
    protected $options;

     /**
     * Set creation options
     *
     * @param  array $options
     * @return void
     */
    public function setCreationOptions( array $options )
    {
        $this->options = $options;
    }


    /**
     * {@inheritdoc}
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        /**
         * @var \Zend\Form\FormElementManager       $serviceLocator
         * @var \Zend\ServiceManager\ServiceManager $serviceManager
         */
        $serviceManager = $serviceLocator->getServiceLocator();
        try
        {
            $options   = /* set up your form's config, you have the service manager here */;
            $form      = new DynamicForm( $options );

            $form->setInputFilter( $serviceManager->get('InputFilterManager')->get( DynamicFormFilter::class, $options ) );
        }
        catch( \Exception $x )
        {
            die( $x->getMessage() );
        }
        return $form;
    }       
}
然后,通过MutableCreationOptions接口实现对DynamicInputFilterFactory中的
$options
做出反应。您通常不希望表单和过滤器具有“选项意识”,让工厂来处理

class DynamicInputFilterFactory implements FactoryInterface, MutableCreationOptionsInterface
{

    protected $options;

    /**
     * Set creation options
     *
     * @param  array $options
     * @return void
     */
    public function setCreationOptions( array $options )
    {
        $this->options = $options;
    }

    public function createService( ServiceLocatorInterface $serviceLocator )
    {
        /* do stuff with $this->options */

        return new DynamicInputFilter(
             /* pass your transformed options */
        );
    }   
}
接下来,您所要做的就是根据通过MutableOptions传递给他们的内容创建表单和输入过滤器。在
\uuuu-construct
中设置依赖项(不要忘记调用parent::\uuu-construct),并根据传入的选项在
init
中初始化表单


我怀疑你在ZF2有很好的基础,所以我就到此为止。这应该会让你上路的。外卖是可变的CreationOptions界面,将InputFilter和表单构造分离,并在表单工厂中将两者结合起来。

我认为,对于动态表单来说,这可能是一种更容易使用的方法。在这篇文章之后,我出去制作了一个小的CLI工具来快速编写表单样板: