symfony 3.4:形式:允许实体的孩子原型

我的目标是创建一本书的章节,在每一章中,我可以拥有任意数量的章节作为子章节。我有一个实体,它是每一章的一本书的一章,我可以添加一个子章(实际上是另一章(但 id parent 不为空))


class Chapter

{       

    /**

     * One champ has One parent champ.

     * @ORM\ManyToOne(targetEntity="Chapter", inversedBy="children")

     * @ORM\JoinColumn(name="id_parent", referencedColumnName="id")

     */

    public $parent; 

    

    /**

     * One champ has Many champs.

     * @ORM\OneToMany(targetEntity="Chapter", mappedBy="parent",cascade={"persist"}))

     * @ORM\OrderBy({"ordre" = "ASC"})

     */

    public $children;   

我想在每一章中使用 symfony 添加/删除/修改,所以我有以下表单类型


public function buildForm(FormBuilderInterface $builder, array $options)

{

    

    $builder->add('libelleLong', textType::class, ['label'=> 'titre']);


    

     $builder->add('children', CollectionType::class,[

         'entry_type' => ChapterType::class,

         'entry_options' => ['label' => false,'block_name' => 'childrenList'],

    

         'block_name' => 'childrenList',

         'label'=> false,

         'allow_add'=>true,

         'allow_delete'=> true,

         'prototype'=> true,

         'by_reference' => false,


         ]

     );             

}

但是这条线'prototype'=> true把一切都放下了......


[2020 年 5 月 19 日 20:57:08 UTC] PHP 致命错误:供应商\symfony\symfony\src\Symfony\Component\Debug\Exception\OutOfMemoryException 中允许的 134217728 字节的内存大小已耗尽(试图分配 32768 字节)。第 1 行的 php


我怎样才能让孩子们使用原型?


MM们
浏览 89回答 1
1回答

aluckdog

我相信,问题最终是递归的。因为子表单也将有一个children字段,所有子表单也将有children字段......无限。因此,它只是为了创建它而耗尽了内存。(这个问题只在添加时发生prototype,因为它必须渲染一个未来的孩子,它也有原型,并且必须做同样的事情 - 请注意,表单组件不是处理递归的最佳装备。也许你可以找到一个技术上和视觉上处理这个问题的不同方式,例如 (pos,string,depth) 元组的列表,通过表单渲染/js 进行光学改进,并进行转换等)所以你必须限制这个递归的深度。一种通用的方法(我不确定这是否有效)是添加一个选项max_depth,它基本上告诉表单生成器它是否可以以及还有多少级别。为此,您的表单类型类应包含一个方法configureOptions:public function configureOptions(OptionsResolver $resolver){    $resolver->setRequired(['max_depth']);    $resolver->setDefaults([        'data_class' => Chapter::class, // you probably have this line!        'max_depth' => 3, // default value    ]);}这会将配置选项添加到您的表单类型,现在我们必须在您的buildForm方法中使用它:public function buildForm(FormBuilderInterface $builder, array $options) {    $builder->add('libelleLong', textType::class, ['label'=> 'titre']);    // only add children sub form, if max_depth > 0, to stop infinite recursion    if($options['max_depth'] > 0) {         $builder->add('children', CollectionType::class,[             'entry_type' => ChapterType::class,             'entry_options' => [                   'label' => false,                   'block_name' => 'childrenList',                   // IMPORTANT!!! reduce max_depth by 1                   'max_depth' => $options['max_depth'] - 1,              ],             'block_name' => 'childrenList',             'label'=> false,             'allow_add' => true,             'allow_delete'=> true,             'prototype'=> true,             'by_reference' => false,         ]);    } // end if for max_depth}我会建议保持max_depth小,比如...... 2 或 3。另一种方法是,创建另一种名为 SubChapterType 和 SubSubChapterType 的表单类型,它们本质上与 ChapterType 相同,只是它们的 是children下entry_type一个表单类型,其中最后一个表单类型没有字段 children。
打开App,查看更多内容
随时随地看视频慕课网APP