简体   繁体   English

Symfony 3.4表单EntityType选择的值为空

[英]Symfony 3.4 form EntityType selected value is empty

I have an issue with Symfony 3.4 EntityType. 我在Symfony 3.4 EntityType中遇到问题。

CategoryType.php 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 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';
    }
}

Form renders as expected: Title as Text field, and 2 select elements. 表单按预期方式呈现:“标题为文本”字段和2个选择元素。 But problem is rendered select element does not select selected value. 但问题是呈现出选择元素未选择所选值。

form.html.twig form.html.twig

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

Result 结果
在此处输入图片说明

Expected result 预期结果
在此处输入图片说明

When in SpecificationType.php EntityType::class is replaced with TextField:class now form renders not 2 select elements bus 2 text inputs (expected behaviour) and values assigned are correct: 当在SpecificationType.php中将EntityType::class替换为TextField:class表单现在不呈现2个select元素总线2个文本输入(预期的行为),并且分配的值正确:
在此处输入图片说明

I started digging how these select elements are rendered in first place, and found that this block {%- block choice_widget_options -%} is responsible for rendering select element. 我开始研究如何首先呈现这些选择元素,并发现此块{%- block choice_widget_options -%}负责呈现选择元素。

Inside this block is peace of code: 此代码块内部是和平的代码:

<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>

Exactly this condition: {% if choice is selectedchoice(value) %} selected="selected"{% endif %} is responsible for adding selected attribute to option. 正是这样的情况: {% if choice is selectedchoice(value) %} selected="selected"{% endif %}负责将selected属性添加到选项。 But value in selectedchoice(value) extension is somehow empty, that's why he is not marking option as selected. valueselectedchoice(value)扩展是有点空,这就是为什么他的选择没有标记选项。

Maybe anyone knows, how to solve this issue? 也许有人知道,如何解决这个问题?

UPDATED 更新

spec property is defined like this: spec属性的定义如下:

CategoryEntity.php CategoryEntity.php

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

Found solution here . 在这里找到解决方案。

As @Nickolaus wrote: 正如@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

So solution is: 所以解决方案是:

Refactor SpecificationType.php like this: 像这样重构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';
    }
}

Use getParent() method, move all field configs to configureOptions and remove buildForm() method. 使用getParent()方法,将所有字段配置移至configureOptions并删除buildForm()方法。

Finally.. so many hours wasted.. 终于..浪费了很多时间..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM