gpt4 book ai didi

forms - Symfony CollectionType 和类继承

转载 作者:行者123 更新时间:2023-12-03 17:38:15 25 4
gpt4 key购买 nike

我正在为一个 Symfony 项目苦苦挣扎,由于我对该框架没有那么丰富的经验,所以我无法弄清楚我是否有设计缺陷,Symfony 是否无法处理我的用例,或者我是否只需要找到正确的方法。
这里是 :
我有一个实体 Row 应该包含 1 到 n 个具有不同内容的项目,如“标题”、“文本”、“图像”等。
由于每个内容都有不同的特征,我通过单表继承从一个名为 RowContent 的抽象类中扩展了每个内容类型。
这是实体的编辑版本:
类(class)行

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 是抽象的)。
所以在我一根一根拔头发之前,我想知道是否有人已经遇到过这样的情况,或者对如何提交表单有任何见解。
谢谢 !

最佳答案

我知道这个问题很老,但我遇到了同样的问题,我设法解决了。我会分享我的解决方案,以防将来有人偶然发现同样的问题。
在这篇文章的时候,我正在使用 symfony 5。

  • 我为每种类型创建了一个表格。例如,在您的情况下,它将是 Title 的一种形式,Text 的一种形式和 Image 的另一种形式(我们分别称它们为 RowTitleContentType、RowTextContentType 和 RowImageContentType)。

  • 我确实创建了一个 AbstractRowContentType 并从中扩展。这样我就不必在每种表单类型中重复公共(public)字段。
  • 然后,在您的 RowType 表单中,为您创建的每个表单类型添加一个 CollectionType,并将“mapped”属性设置为 false。换句话说,它看起来像这样:
     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,
    ))
    ;
    }
  • 现在我们需要设置一个监听器来合并内容并将它们添加到 RowContent 对象中:
     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));
    });
    }

  • 就是这样。希望它可以帮助某人。
    顺便说一句,我的解决方案是基于这篇文章: Build Form with Single Table Inheritance

    关于forms - Symfony CollectionType 和类继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43205202/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com