【问题标题】:How can I pass an iteration specific variable to the Form Builder in the Form Collection in Symfony 3?如何在 Symfony 3 的表单集合中将迭代特定变量传递给表单生成器?
【发布时间】:2017-10-05 00:54:30
【问题描述】:

我有一个包含不同问题(项目)的评估,每个项目都有特定数量的可能选择。

我需要传递选项的数量和每个问题的标签来为每个项目(问题)构建表单。

我可以将变量从“父”表单传递到表单集合,但我不知道如何在评估“答案”属性中传递特定于每次迭代的变量。

在我的控制器中:

$evaluation = new Evaluation();
$answers = array();
// i set each answer to default 0, for the form to place them in view
foreach ($items as $index => $item) {
    $answers[$index] = array('value' => 0, 'item_id' => $item->getId());
}
$evaluation->setAnswers($answers);

$formBuilder = $this->createFormBuilder($evaluation);

$formBuilder->add("answers", CollectionType::class, array(
    'entry_type' => AnswerType::class,
    //here i pass all the items objects array to the AnswerType form.
    'entry_options' => array(
        'items' => $items,
    ),
    'allow_delete' => false,
    'allow_add' => false,
));

比在 AnswerType 表单类中:

class AnswerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $choices = array();

        // here I have all the items available in $options['items'];
        // but each item has a specific number of choices, and I need the current one that is being built
        // and I also need other info form the item like the question it self

        for($i = 1; $i <= $current_item_number_of_choices_that_i_dont_have;$i++){
            $choices[$i] = $i;
        }

        $builder->add('value', ChoiceType::class, array(
            'choices_as_values' => true,
            'multiple'=>false,
            'expanded'=>true,
            'choices' => $choices,
            'label' => $current_item_text_label_that_I_also_need
        ));

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'items' => null
        ));
    }
}

谢谢! :)

【问题讨论】:

  • 实际上我在 $options 数组中找到了一个“property_path”,它作为答案数组“[0]”、“[1]”、“[2]”的索引的字符串化版本传递“......我可以解析并使用它访问 items 数组。但似乎很粗略......必须有一个“官方”的方式......
  • 您的 AnswerType 类中的选择来自哪里?
  • 我在那里生成它们,从 1 到当前项目的最大值,即动态的..
  • 所以你的选择是'1'、'2'、'3'、'4'等等?但是每个人都有一个标签?我想我应该问一下你的标签是从哪里来的。如果来自数据库,那么您似乎正在使这变得更加复杂,但也许我不明白您的问题。
  • 所以,对于项目 1,选择是 1,2 和 3,但对于项目 2,选择是 1,2,3,4,5,对于项目 3,它们是 1....9等等..标签也是1,2,3..

标签: php symfony formbuilder symfony-3.2


【解决方案1】:

CollectionType 可能不是您现在需要的类型来实现它,因为它隐藏了您需要处理的层(当前项)。所以最好自己添加答案集合。像这样的:

class AnswerCollectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach ($options['items'] as $index => $item) {
            $builder->add($index + 1, AnswerType::class, [
                'item' => $item,
            ]);
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired('items');
    }
}

class AnswerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $item = $options['item'];

        $choices = [];
        for ($i = 1; $i <= $item->getNumChoices(); $i++) {
            $choices[$i] = $i;
        }

        $builder->add('value', ChoiceType::class, [
            'label' => $item->getLabel(),
            'choices' => $choices,
            'expanded' => true,
        ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired('item');
    }
}

请注意,AnswerType 现在需要 item 选项才能正确构建当前选择表单。

$formBuilder->add('answers', AnswerCollectionType::class, [
    'items' => $items,
])

另一方面,CollectionType 的解决方法更复杂(通过使用事件)需要静态内部计数器来了解当前项目。

详情请见http://symfony.com/doc/current/form/dynamic_form_modification.html

【讨论】:

  • 效果很好!谢谢! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-25
  • 2019-05-23
  • 2014-10-11
  • 1970-01-01
  • 2019-11-19
  • 2019-05-27
  • 1970-01-01
相关资源
最近更新 更多