使用Doctrine扩展树准备更新层次结构类别的选项

时间:2016-01-27 08:09:21

标签: symfony doctrine-orm doctrine-extensions

我使用Doctrine extension tree在symfony项目中以分层方式管理类别。

尽管如此,我还没有找到如何简单地管理树枝中的添加/编辑部分: 我可以用childrenHierarchy()方法显示html树结构,但我想更进一步,有类似的东西:

Root
- Cat 1  (+)
-- Cat 1-1  (+)
-- Cat 1-2  (+)
- Cat 2  (+)

(+)会打开一个显示(类别)文本字段的模式,允许在选定的父级上分支此元素。

我还没有在文档中看到过(并且我不会,如果可能的话)使用这种方法childrenHierarchy()可以选择允许额外的html,使用ajax调用

我的实体是基本的:

<?php
namespace CPASimUSante\SimupollBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Claroline\CoreBundle\Entity\User;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * Simupoll categories
 *
 * @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
 * @ORM\Table(
 *      name="cpasimusante__simupoll_category",
 *      uniqueConstraints={
 *          @ORM\UniqueConstraint(name="category_unique_name_and_user", columns={"user_id", "name"})
 *      }
 * )
 * @DoctrineAssert\UniqueEntity({"name", "user"})
 * @Gedmo\Tree(type="nested")
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * name of the category
     * @var string $value
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    /**
     * @Gedmo\TreeLeft
     * @ORM\Column(name="lft", type="integer")
     */
    private $lft;

    /**
     * @Gedmo\TreeLevel
     * @ORM\Column(name="lvl", type="integer")
     */
    private $lvl;

    /**
     * @Gedmo\TreeRight
     * @ORM\Column(name="rgt", type="integer")
     */
    private $rgt;

    /**
     * @Gedmo\TreeRoot
     * @ORM\Column(name="root", type="integer", nullable=true)
     */
    private $root;

    /**
     * @Gedmo\TreeParent
     * @ORM\ManyToOne(
     *     targetEntity="CPASimUSante\SimupollBundle\Entity\Category",
     *     inversedBy="children"
     * )
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $parent;

    /**
     * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\User")
     */
    private $user;

    /**
     * @ORM\OneToMany(
     *     targetEntity="CPASimUSante\SimupollBundle\Entity\Category",
     *     mappedBy="parent",
     * )
     * @ORM\OrderBy({"lft" = "ASC"})
     */
    protected $children;

    /**
     * propoerty used in hierarchy display, like selectbox
     */
    private $indentedName;

    public function __construct()
    {
        $this->children = new ArrayCollection();
    }

    /**
     * Returns the resource id.
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Sets the resource id.
     * Required by the ResourceController when it creates a fictionnal root
     *
     * @param integer $id
     */
    public function setId($id)
    {
        $this->id = $id;
    }

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

    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * Returns the children resource instances.
     *
     * @return \Doctrine\Common\ArrayCollection|Category[]
     */
    public function getChildren()
    {
        return $this->children;
    }

    /**
     * Returns the parent category.
     *
     * @return \CPASimUSante\SimupollBundle\Entity\Category
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Sets the parent category.
     *
     * @param \CPASimUSante\SimupollBundle\Entity\Category $parent
     */
    public function setParent(\CPASimUSante\SimupollBundle\Entity\Category $parent = null)
    {
        $this->parent = $parent;
    }

    /**
     * Return the lvl value of the resource in the tree.
     *
     * @return integer
     */
    public function getLvl()
    {
        return $this->lvl;
    }

    public function getUser()
    {
        return $this->user;
    }

    public function setUser(User $user)
    {
        $this->user = $user;
    }

    /**
     * allows hierachy display
     * @return string
     */
    public function __toString()
    {
        return $this->getName();
    }

    /**
     * allows hierachy display
     * @return string
     */
    public function getIndentedName()
    {
        return str_repeat("--", $this->lvl) . $this->name;
        //return str_repeat($this->getParent()." > ", $this->lvl) . $this->name;
    }
}

我的控制器目前基本也是,我认为我可以调整选项:

    public function indexAction(Simupoll $simupoll)
    {
        $em = $this->getDoctrine()->getManager();
        $user = $this->container
            ->get('security.token_storage')
            ->getToken()->getUser();
        $repo = $em->getRepository('CPASimUSanteSimupollBundle:Category');
        $options = array(
            'decorate' => true,
            'rootOpen' => '<ul>',
            'rootClose' => '</ul>',
            'childOpen' => '<li>',
            'childClose' => '</li>'
        );
        $htmlTree = $repo->childrenHierarchy(
            null, /* starting from root nodes */
            false, /* true: load all children, false: only direct */
            $options
        );
        return array(
            '_resource' => $simupoll,
            'tree' => $htmlTree,
        );
    }

模板是:

{% block section_content %}
    <div class="panel panel-default">
        <div class="panel-body" id="text_content">
            {{ tree |raw }}
        </div>
    </div>
{% endblock %}

如果有人有建议或领导,请提前感谢。

1 个答案:

答案 0 :(得分:0)

实际上,nodeDecorator选项允许自定义输出:

$options = array(
    'decorate' => true,
    'rootOpen' => '<ul>',
    'rootClose' => '</ul>',
    'childOpen' => '<li>',
    'childClose' => '</li>',
    'nodeDecorator' => function($node) {
        return $node['name']. '<a href="#" data-id="'.$node['id'].'" class="btn btn-primary category-add-btn">+</a>';
    }
);

然后我可以在树枝模板中使用一些j来显示模态。

$('#treecontainer').on('click', '.category-add-btn', function(){
    //logic to display modal and pass parameter
});