Forms Symfony CollectionType&;类继承
我正在为一个Symfony项目苦苦挣扎,由于我对这个框架没有太多经验,我无法确定我是否有设计缺陷,Symfony是否无法处理我的用例,或者我是否只需要找到正确的方法 这是: 我有一个实体行,它应该包含1到n个具有不同内容的项目,如“标题”、“文本”、“图像”等 由于每个内容都有不同的特征,我通过单表继承从一个名为RowContent的抽象类扩展了每个内容类型。 以下是实体的编辑版本: 班级排Forms Symfony CollectionType&;类继承,forms,symfony,inheritance,Forms,Symfony,Inheritance,我正在为一个Symfony项目苦苦挣扎,由于我对这个框架没有太多经验,我无法确定我是否有设计缺陷,Symfony是否无法处理我的用例,或者我是否只需要找到正确的方法 这是: 我有一个实体行,它应该包含1到n个具有不同内容的项目,如“标题”、“文本”、“图像”等 由于每个内容都有不同的特征,我通过单表继承从一个名为RowContent的抽象类扩展了每个内容类型。 以下是实体的编辑版本: 班级排 class Row { //..... /** * @var ArrayCo
class Row
{
//.....
/**
* @var ArrayCollection $rowContents
*
* @ORM\OneToMany(targetEntity="RowContent", mappedBy="row", cascade={"persist", "remove", "merge"})
*/
private $rowContents;
//...
}
课程内容:
/**
* RowContent
*
* @ORM\Table(name="row_content")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({
* "title" = "Kinkinweb\BaseBundle\Entity\Content\Title",
* "text" = "Kinkinweb\BaseBundle\Entity\Content\Text",
* "image" = "Kinkinweb\BaseBundle\Entity\Content\Image",
* })
* @ORM\Entity(repositoryClass="Kinkinweb\BaseBundle\Repository\RowContentRepository")
*/
abstract class RowContent
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
//...
}
例如,文本类:
/**
* Text
*
* @ORM\Table(name="content_text")
* @ORM\Entity(repositoryClass="Kinkinweb\BaseBundle\Repository\Content\TextRepository")
*/
class Text extends RowContent
{
/**
* @var string
*
* @ORM\Column(name="text", type="string", length=255)
*/
private $text;
//...
}
到目前为止还不错,但我不能处理所有这些表格提交。。。
要使用这些实体处理表单,我目前有以下FormType:
class RowType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//...
->add('rowContents', CollectionType::class, array(
'entry_type' => RowContentType::class,
'allow_add' => true,
'allow_delete' => true,
'label' => 'Contenu Flexible',
'by_reference' => false,
'block_name' => 'rows',
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Kinkinweb\BaseBundle\Entity\Row',
));
}
}
我对buildForm部分的处理如下:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, function($e) {
if (null === $e->getData()) { return; }
$form = $e->getForm();
if ($e->getData() instanceof Text){
$form->add('text',TextType::class);
}
});
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Kinkinweb\BaseBundle\Entity\RowContent';
));
}
但是当我使用jQuery在表单中添加内容并提交表单时,框架无法处理提交的RowContent对象(因为RowContent是抽象的,所以对我来说似乎是合乎逻辑的)
所以在我一个接一个地拔头发之前,我想知道是否有人遇到过这样的情况,或者对如何提交我的表格有什么见解
谢谢 我知道这个问题很老,但我也遇到了同样的问题,我设法解决了它。我将分享我的解决方案,以防将来有人在同一问题上犯错 在写这篇文章的时候,我正在使用symfony5
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//...
->add('rowTitleContents', CollectionType::class, array(
'entry_type' => RowTitleContentType::class,
'mapped' => false,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
->add('rowTextContents', CollectionType::class, array(
'entry_type' => RowTextContentType::class,
'mapped' => false,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
->add('rowImageContents', CollectionType::class, array(
'entry_type' => RowImageContentType::class,
'mapped' => false,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
//..
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$row = $event->getData();
$form = $event->getForm();
//let's get every content from the form
$rowTitleContents = $form->get('rowTitleContents')->getData();
$rowTextContents = $form->get('rowTextContents')->getData();
$rowImageContents = $form->get('rowImageContents')->getData();
//Let's merge everything
$mergedRowContents = array_merge($rowTitleContents,
$rowTextContents, $rowImageContents);
// And now we add everything to the object.
$row->setRowContents(new ArrayCollection($mergedRowContents));
});
}