我尝试在其中创建一个带有嵌入形式的复杂表单。
表单需要同时创建/修改2个实体:Instrument
和Specification
。
在解释表单问题之前的一些重要信息:
这两个实体之间没有学说关系,因为Specification
并不总是同一个类。例如,如果Instrument
是吉他,则该类为GuitarSpecification
,如果乐器是录音机,则该类为RecorderSpecification
。
Doctrine无法处理这种类型的关系,所以我手动管理它:
Instrument
实体作为属性specification
,具有关联的getter / setter Specification
实体在Instrument
通过Doctrine Events的同时被加载,保留,删除。Instrument的根表格是(简易版):
class InstrumentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->setRequestHandler(new JsonApiRequestHandler());
$builder
->add('name', TextType::class)
// ... other fields
;
// Add specification
$formModifier = function(FormInterface $form, \InstrumentBundle\Entity\InstrumentType $instrumentType = null) {
$prefix = null === $instrumentType ? 'Abstract' : $instrumentType->getPrefix();
$form->add('specification', 'InstrumentBundle\\Form\\Specification\\' . $prefix . 'SpecificationType');
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) use ($formModifier) {
// Get Instrument Entity
$data = $event->getData();
$formModifier($event->getForm(), $data->getInstrumentType());
}
);
$builder->get('instrumentType')->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($formModifier) {
// Get Instrument Entity
$instrumentType = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $instrumentType);
}
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'csrf_protection' => false,
'cascade_validation' => true,
'data_class' => 'InstrumentBundle\Entity\Instrument'
]);
}
}
这种形式的孤独复杂性是有事件监听器(PRE_SET_DATA
和POST_SUBMIT
)检查Instrument
(吉他,录音机等)的类型并添加正确的Specification
表格(GuitarSpecification,RecorderSpecification等)。
以下是我的Specification
表单类型之一的示例:
class GuitarSpecificationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('leftHanded', CheckboxType::class)
->add('headstock', TextType::class)
->add('body', TextType::class)
->add('amplification', TextType::class)
->add('strings', IntegerType::class)
->add('frets', IntegerType::class)
->add('tuning')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'csrf_protection' => false,
'data_class' => 'InstrumentBundle\Entity\Specification\GuitarSpecification'
]);
}
}
我的问题是提交表单时,Specification
的Request数组部分未转换为实体,我收到错误:
Expected argument of type "InstrumentBundle\Entity\Specification\AbstractSpecification", "array" given
我无法找到解决这个问题的方法,所以欢迎任何想法。
答案 0 :(得分:0)
只是一个问题,它不可能解决您的不同规范问题'使用Doctrine2的继承映射?