【问题标题】:Symfony formbuilder self-reference entity groupedSymfony formbuilder自引用实体分组
【发布时间】:2014-01-04 11:47:20
【问题描述】:

我想要一个按父类别(不可选择)分组的选择列表(下拉列表)。 这甚至可能吗?

Example:
 - Vehiculs (not selectable)
 -- Car (selectable)
 -- Boat (selectable)
 - Computers (not selectable)

实体类别

    /**
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
     **/
    private $children;

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     **/
    private $parent;

表格:

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text',
                [
                    'attr' => ['placeholder' => 'Titel', 'class' => 'form-control', 'autocomplete' => 'off'],
                    'label' => false
                ]
            )
            ...
            ->add('category', 'entity',
                [
                    'property' => 'name',
                    'class' => '***ArticleBundle:Category',
                ]
            )
        ;
    }

使用上面的代码,我只能得到父母,他们是可选择的。 我想将这些父母的孩子分组(1 个深度),并只让孩子们可选择选项。

【问题讨论】:

    标签: symfony doctrine-orm self-reference formbuilder


    【解决方案1】:

    之所以发布这个,是因为这似乎是谷歌第一次遇到这个问题,我必须解决它。

    实际上,您可以直接告诉 symfony 在 FormBuilder 中创建一个树选择,只需一个完全干净的小变通方法。

    “实体”是“选择”的子项这一事实对此有很大帮助。该解决方案由三部分组成:Controller、FormType 和 Entity Repository 让我们从控制器开始

    $em = $this->getDoctrine()->getManager();    
    $form = $this->createForm(new AcmeType(array(
                'repository' => $em->getRepository('AcmeBundle:Category'),
            )), $data, array(
                'action' => *add your route here*
                'method' => 'POST'
            ));
    

    直接生成表单,除了将存储库添加为您的 FormType 的参数(我们需要在那里)

    您的 FormType 包括以下内容

        /** @var CategoryRepository */
        protected $repository;
    
        public function __construct($options = array()){
            $this->repository = $options['repository'];
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                *add your other stuff here*
                ->add('category', 'entity', array(
                    'empty_value' => 'Please Select...',
                    'required' => true,
                    'choices' => $this->repository->getCategoryData(),
                    'class' => 'Acme\AcmeBundle\Entity\Category'
                ))
            ;
        }
    

    我们创建一个实体字段类型并添加“选择”并用来自“getCategoryData”的响应填充它。

    在您的数据实体(在本例中为类别实体)的存储库中,您创建以下函数

    public function getCategoryOptions()
    {
        $data = array();
        $categories = $this
            ->createQueryBuilder('c')
            ->select('c')
            ->getQuery()
            ->getResult();
    
        foreach( $categories as $category ){
            /** @var Category $category */
            if( !$category->getParent() ){
                continue;
            }
            if(!array_key_exists($category->getParent()->getName(), $data) ){
                $data[$category->getParent()->getName()] = array();
            }
            $data[$category->getParent()->getName()][$category->getId()] = $category;
        }
        return $data;
    }
    

    这个简单的函数对数据库进行简单查询以选择您的类别,然后通过它们运行 foreach 并构建一个数组。如上面的 FormType 所示,它将该数组直接解析为实体字段类型的“选择”参数。 symfony 的 Form Renderer 很聪明,可以添加带有标签的标签。

    瞧,您有一个分组下拉框,其中包含不可选择的“父母”。

    【讨论】:

      【解决方案2】:

      您不能直接告诉 symfony 在表单构建器中创建树选择。

      首先,你必须在这里检查; http://symfony.com/doc/current/reference/forms/types/entity.html

      您可以在实体字段上使用查询构建器来获取父子关系,但父母也可以选择。

      因此,您必须查看其他解决方案,如下所示: How to disable specific item in form choice type?

      【讨论】:

        猜你喜欢
        • 2014-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        • 2014-09-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多