Zend framework2 zf2:将动态数据传递到FormCollection中的选择

Zend framework2 zf2:将动态数据传递到FormCollection中的选择,zend-framework2,zend-form,Zend Framework2,Zend Form,我尝试使用zf2表单集合。 上传考试后,我得到了一组ExamQuestion对象,我想提供一个表单,用户可以在其中为每个问题选择主题。 可用的主题来自数据库 我的第一个问题是,我不知道如何为Zend\Form\Element\Collection字段集中的Select元素设置动态值选项。如果您阅读以下简化代码,您将了解我的解决方案: class ExamController { public function questionAction() { // parse exa

我尝试使用zf2表单集合。 上传考试后,我得到了一组ExamQuestion对象,我想提供一个表单,用户可以在其中为每个问题选择主题。 可用的主题来自数据库

我的第一个问题是,我不知道如何为Zend\Form\Element\Collection字段集中的Select元素设置动态值选项。如果您阅读以下简化代码,您将了解我的解决方案:

class ExamController {
    public function questionAction() {
        // parse exam ...

        $questions = $parser->getQuestions();
        $subjects = Subject::sorted()->get();

        $form = new ExamQuestionForm($questions, $subjects);
        $this->viewModel->setVariable('form', $form);
        return $this->view();
    }
}



class ExamQuestionForm {
    public function __construct($questions, $subjects) {
        parent::__construct('examquestionform');

        $this->add(array(
            'type' => 'Zend\Form\Element\Collection',
            'name' => 'questions',
            'options' => array(
                'label' => 'Prüfungsfragen',
                'count' => count($questions),
                'should_create_template' => true,
                'allow_add' => true,
                'target_element' => array(
                    'type' => 'Application\Form\QuestionFieldset',
                ),
            ),
        ));

        $this->add(array(
            'name' => 'submit',
            'type' => 'Submit',
            'attributes' => array(
                'value' => 'Speichern',
                'id' => 'submitbutton',
            ),
        ));

        /*
         * The following code does not work.
         * $collection->getFieldsets() returns an empty array.
         * But the form is rendered if i remove that so the fieldsets must be there?
         */
        $collection = $this->get('questions');
        $questionFieldsets = $collection->getFieldsets();
        for ($i = 0; $i < count($questions); $i++) {
            $questionFieldsets[$i]->setQuestion($questions[$i]);
            $questionFieldsets[$i]->setSubjects($subjects);
        }
    }
}



class QuestionFieldset extends Fieldset {
    public function __construct($name = null) {

        parent::__construct('question');

        /*
         * Here should be a plain text element for the question text.
         */

        $this->add(array(
            'name' => "subject",
            'type' => 'Select',
            'options' => array(
                'label' => 'Fach',
                'value_options' => array(),
            ),
        ));
    }

    /**
     * Prepares the fieldset with question data.
     *
     * @param \ExamQuestion $question
     */
    public function setQuestion($question) {
        $this->setLabel('Frage '.$question->number);
        // Here the plain text element from above should be added ...
    }

    /**
     * Adds passed subjects as options in subject select element.
     *
     * @param array $subjects Subject objects.
     */
    public function setSubjects($subjects) {

        $valueOptions = array();
        foreach ($subjects as $subject) {
            $valueOptions[$subject->id] = $subject->name;
        }
        $this->get('subject')->setValueOptions($valueOptions);
    }
}
模板很简单:

<?php
$form = $this->form;
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formCollection($form->get('questions'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
?>
这似乎不是正确的方法。甚至它也不起作用。
有人能解释一下如何正确处理这项任务吗?

最后我自己找到了一个解决方案

首先,$collection->getfieldset方法只有在调用$form->prepare之前才能正常工作。因此,将数据传递到集合字段集不是一种好方法,因为应该在视图模板中调用prepare函数

一种可能的解决方案不是配置集合并随后操作其字段集,而是在代码中自己创建和准备字段集,并将其添加到空集合中。请注意,每个字段集都需要一个唯一的名称