Symfony 3.4表单EntityType选中的值为空

时间:2018-06-07 12:04:07

标签: php symfony twig symfony-3.4

我遇到Symfony 3.4 EntityType的问题。

CategoryType.php

class CategoryType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('spec', CollectionType::class, [
                'entry_type' => SpecificationType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'label' => false,
            ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Category::class,
        ));
    }
}

SpecificationType.php

class SpecificationType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title', EntityType::class, [
            'class' => Specification::class,
            'label' => false,
        ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Specification::class,
        ));
    }

    public function getBlockPrefix()
    {
        return 'specification';
    }
}

表格按预期渲染:标题为文本字段,以及2个选择元素。但问题是渲染选择元素不选择选定的值。

form.html.twig

{{ form_widget(form.title) }}
{{ form_widget(form.spec) }}

结果
enter image description here

预期结果
enter image description here

SpecificationType.php EntityType::class被替换为TextField:class时,表单呈现不是2个选择元素总线2文本输入(预期行为)和分配的值是正确的:
enter image description here

我开始挖掘这些选择元素是如何首先渲染的,并发现这个块{%- block choice_widget_options -%}负责渲染select元素。

在这个街区内是代码的和平:

<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>

正是这种情况:{% if choice is selectedchoice(value) %} selected="selected"{% endif %}负责将selected属性添加到选项中。但value扩展程序中的selectedchoice(value)在某种程度上是空的,这就是为什么他没有将选项标记为已选中。

也许有人知道,如何解决这个问题?

已更新

spec属性的定义如下:

CategoryEntity.php

/**
 * @ORM\ManyToMany(targetEntity="Specification", inversedBy="categoryList")
 * @ORM\JoinTable(name="category_specification")
 */
private $spec;

1 个答案:

答案 0 :(得分:1)

找到解决方案here

正如@Nickolaus所写:

[..] You are having this problem because it is a compound form in your implementation and no simple form and symfony is unable to resolve which field created inside the subform needs to be used as source for the entity field

所以解决方案是:

像这样重构SpecificationType.php

class SpecificationType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'class' => Specification::class,
            'label' => false,
        ));
    }

    public function getParent()
    {
        return EntityType::class;
    }

    public function getBlockPrefix()
    {
        return 'specification';
    }
}

使用getParent()方法,将所有字段配置移至configureOptions并移除buildForm()方法。

最后......浪费了这么多时间..