下拉选项结构

时间:2014-08-28 08:57:09

标签: symfony

我需要在表单中为我的类别选项列表创建树结构。 我的选项列表的表单类型代码:

->add('discipline', 'entity', array('label' => 'Parent Discipline',
    'empty_value'   => 'Parent Discipline...',
    'required'      => true,
    'empty_data'    => null,
    'class'         => 'RFQ\IronilBundle\Entity\ProductionType',
    'query_builder' => function(ProductionTypeRFQRepository $er) {return  $er->createQueryBuilder('w')->where('w.parent IS NULL')->addOrderBy('w.name', 'ASC');},
    'attr'          => array('class'=>'form-control login-input')))

正如您所看到的,我已经连接了Repository,它将从树结构中的数据库中获取选项列表,但我不知道如何做到这一点。现在我的存储库看起来像这样:

    <?php

namespace RFQ\IronilBundle\Entity;

use Doctrine\ORM\EntityRepository;

class ProductionTypeRFQRepository extends EntityRepository
{
    public function findAllParents()
    {
        return $this->getEntityManager()
            ->createQuery('SELECT p FROM RFQIronilBundle:ProductionType p WHERE p.parent IS NULL ORDER BY p.name ASC')
            ->getResult();
    }

    public function findAll()
    {
        return $this->findBy(array(), array('name' => 'ASC'));
    }
}

此存储库仅获取父级,但不获取数据库中的子级。

请提供一些信息,在哪里找到解决方案。

修改

对于请求,这是我的类别实体:

    <?php

namespace RFQ\IronilBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * ProductionType
 *
 * @ORM\Table(name="production_type")
 * @ORM\Entity(repositoryClass="RFQ\IronilBundle\Entity\ProductionTypeRepository")
 * @ORM\Entity(repositoryClass="RFQ\IronilBundle\Entity\ProductionTypeRFQRepository")
 */
class ProductionType
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     * @ORM\OneToMany(targetEntity="RFQ", mappedBy="discipline")
     */
    protected $name;

    /**
     * @ORM\OneToMany(targetEntity="ProductionType", mappedBy="parent")
     * @ORM\OrderBy({"name" = "ASC"})
     **/
    protected $children;

    /**
     * @ORM\ManyToOne(targetEntity="ProductionType", inversedBy="children")
     **/
    protected $parent;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->children = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Set name
     *
     * @param string $name
     * @return ProductionType
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add children
     *
     * @param \RFQ\IronilBundle\Entity\ProductionType $children
     * @return ProductionType
     */
    public function addChild(\RFQ\IronilBundle\Entity\ProductionType $children)
    {
        $this->children[] = $children;

        return $this;
    }

    /**
     * Remove children
     *
     * @param \RFQ\IronilBundle\Entity\ProductionType $children
     */
    public function removeChild(\RFQ\IronilBundle\Entity\ProductionType $children)
    {
        $this->children->removeElement($children);
    }

    /**
     * Get children
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getChildren()
    {
        return $this->children;
    }

    /**
     * Set parent
     *
     * @param \RFQ\IronilBundle\Entity\ProductionType $parent
     * @return ProductionType
     */
    public function setParent(\RFQ\IronilBundle\Entity\ProductionType $parent = null)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Get parent
     *
     * @return \RFQ\IronilBundle\Entity\ProductionType
     */
    public function getParent()
    {
        return $this->parent;
    }

    public function __toString()
    {
        return $this->name;
    }
}

我的RFQ的实体,其中我需要这个带有类别的树结构(我已经删除了所有不需要问题的项目):

    <?php

namespace RFQ\IronilBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * RFQ
 *
 * @ORM\Table(name="rfq")
 * @ORM\Entity
 */
class RFQ
{
    //RFQ overall
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="ProductionType",inversedBy="name")
     * @ORM\JoinColumn(referencedColumnName="id")
     **/
    protected $discipline;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set discipline
     *
     * @param \RFQ\IronilBundle\Entity\ProductionType $discipline
     * @return RFQ
     */
    public function setDiscipline(\RFQ\IronilBundle\Entity\ProductionType $discipline = null)
    {
        $this->discipline = $discipline;

        return $this;
    }

    /**
     * Get discipline
     *
     * @return \RFQ\IronilBundle\Entity\ProductionType 
     */
    public function getDiscipline()
    {
        return $this->discipline;
    }
}

1 个答案:

答案 0 :(得分:0)

随着一些咖啡和能量饮料,我设法解决了我的问题。我会在这里写一些类似教程的东西来帮助每个遇到这个问题的人,因为很难找到一个很好的教程如何去做。

  1. 将这些捆绑包添加到composen.json并运行composer update

    "yavin/symfony-form-tree": "dev-master",
    "gedmo/doctrine-extensions": "dev-master",
    "stof/doctrine-extensions-bundle": "1.1.*@dev"
    

    指向包的链接:symfony-form-tree; DoctrineExtensions; StofDoctrineExtensionsBundle

  2. 添加捆绑后,您需要在AppKernel.php

    中注册StofDoctrineExtensionBundle

    new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle()

  3. 现在您需要将正确的Gedmo注释添加到类别实体(我的类别调用ProductionType.php

    <?php
    
    namespace RFQ\IronilBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Gedmo\Mapping\Annotation as Gedmo;
    
    /**
     * @ORM\Entity
     * @ORM\Table(name="production_type")
     * @Gedmo\Tree(type="nested")
     * @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
     */
    class ProductionType
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @ORM\Column(type="string")
         * @ORM\OneToMany(targetEntity="RFQ", mappedBy="discipline")
         */
        protected $name;
    
        /**
         * @ORM\OneToMany(targetEntity="ProductionType", mappedBy="parent")
         * @ORM\OrderBy({"name" = "ASC"})
         **/
        protected $children;
    
        /**
         * @ORM\ManyToOne(targetEntity="ProductionType", inversedBy="children")
         * @Gedmo\TreeParent
         **/
        protected $parent;
    
        /**
         * @var integer
         *
         * @Gedmo\TreeLeft
         * @ORM\Column(type="integer")
         */
        private $treeLeft;
    
        /**
         * @var integer
         *
         * @Gedmo\TreeLevel
         * @ORM\Column(type="integer")
         */
        private $treeLevel;
        /**
         * @var integer
         *
         * @Gedmo\TreeRight
         * @ORM\Column(type="integer")
         */
        private $treeRight;
        /**
         * @var integer
         *
         * @Gedmo\TreeRoot
         * @ORM\Column(type="integer", nullable=true)
         */
        private $treeRoot;
    
        // Generated setters and getters
    
  4. 为您的地图添加扩展程序并激活您需要的扩展程序(在我的案例中为树)

    stof_doctrine_extensions:
        orm:
            default:
                tree: true
    
  5. 现在您需要使用symfony-form-tree。首先将服务添加到Resources/config/services.xml

    <service id="symfony.form.type.tree" class="Yavin\Symfony\Form\Type\TreeType">
       <argument type="service" id="property_accessor"/>
       <tag name="form.type" alias="y_tree"/>
    </service>
    
    <service id="symfony.form.type_guesser.tree" class="Yavin\Symfony\Form\Type\TreeTypeGuesser">
       <argument type="service" id="doctrine"/>
       <tag name="form.type_guesser"/>
    </service>
    
  6. 最后,您需要为symfony-form-tree创建表单构建器以创建分层下拉选项列表:

    ->add('discipline', 'y_tree', array(
        'class' => 'RFQ\IronilBundle\Entity\ProductionType', // tree class
        'levelPrefix' => '--',
        'orderFields' => array('treeRoot', 'treeLeft'),
        'prefixAttributeName' => 'data-level-prefix',
        'treeLevelField' => 'treeLevel',
    ))
    
  7. 这就是全部!我并不是说这是制作分层下拉选项列表的正确方法,也许我犯了一些错误,但这对我来说是完美的。