Php Symfony 3.4表单EntityType所选值为空
我对Symfony 3.4 EntityType有问题 CategoryType.phpPhp Symfony 3.4表单EntityType所选值为空,php,symfony,twig,symfony-3.4,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', Col
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,
));
}
}
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_widget(form.title) }}
{{ form_widget(form.spec) }}
/**
* @ORM\ManyToMany(targetEntity="Specification", inversedBy="categoryList")
* @ORM\JoinTable(name="category_specification")
*/
private $spec;
SpecificationType.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,
));
}
}
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_widget(form.title) }}
{{ form_widget(form.spec) }}
/**
* @ORM\ManyToMany(targetEntity="Specification", inversedBy="categoryList")
* @ORM\JoinTable(name="category_specification")
*/
private $spec;
表单按预期呈现:标题为文本字段,2个选择元素。但问题是渲染选择元素并没有选择选定值
form.html.twig
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,
));
}
}
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_widget(form.title) }}
{{ form_widget(form.spec) }}
/**
* @ORM\ManyToMany(targetEntity="Specification", inversedBy="categoryList")
* @ORM\JoinTable(name="category_specification")
*/
private $spec;
结果预期结果
当在
SpecificationType.php
EntityType::class
中被替换为TextField:class
时,现在表单呈现的不是2个选择元素,而是2个文本输入(预期行为),分配的值正确:我开始挖掘这些select元素最初是如何呈现的,发现这个block
{%-block choice\u widget\u 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>
找到了解决办法
正如@Nickolaus所写的:
[…]您遇到了这个问题,因为在您的实现中它是一个复合表单,没有简单的表单,而且symfony无法解析在子表单中创建的哪个字段需要用作实体字段的源
因此,解决方案是:
重构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()
方法
最后。。浪费了这么多时间。您能展示一下
spec
属性是如何在Category
实体中定义的吗?@Djengobarm请查看更新部分。