zf2:将动态数据传递给FormCollection

时间:2015-11-09 19:05:05

标签: zend-framework2 zend-form

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

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

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();
?>

这似乎不是正确的方法。即使它不起作用。 任何人都可以解释如何正确处理这项任务吗?

1 个答案:

答案 0 :(得分:0)

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

首先,如果您之前调用$ form-&gt; prepare(),$ collection-&gt; getFieldsets()方法才能正常工作。所以它不是将数据传递到集合字段集的好方法,因为应该在视图模板中调用prepare()函数。

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