我需要为FancyTree(JSON格式)构建类别树,所以我这样做:
类别实体
class Category
{
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true)
*/
private $parent;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Category", mappedBy="parent")
*/
private $children;
// ...
public function __construct()
{
$this->children = new ArrayCollection();
}
// ...
/**
* @return Category
*/
public function getParent(): Category
{
return $this->parent;
}
/**
* @return Collection|Category[]
*/
public function getChildren()
{
return $this->children;
}
}
和构建树的方法:
public function buildCategoryTree($categories, ?int $activeCategory = null)
{
$tree = [];
foreach ($categories as $category) {
$tmp = [
"title" => $category->getName(),
"expanded" => true,
"folder" => true
];
if ($category->getId() === $activeCategory)
$tmp['active'] = true;
if ($category->getChildren() != null)
$tmp['children'] = $this->buildCategoryTree($category->getChildren(), $activeCategory);
$tree[] = $tmp;
}
return $tree;
}
但是我得到无限循环 - 为什么? 我得到了所有指定类别的孩子的正确答案(我不会手动添加它),我可以毫无问题地进行迭代。
答案 0 :(得分:0)
function buildTree($categories, $parentCategory = null) {
$branch = array();
foreach ($categories as $element) {
if ($element->getParent() == $parentCategory) {
$children = buildTree($categories, $element);
if ($children) {
$element->getChildren() = $children;
}
$branch[$element->getId()] = $element;
unset($categories[$element->getId()]);
}
}
return $branch;
}
请检查一下:
<?php
use Doctrine\Common\Collections\ArrayCollection;
/** @ORM\Entity */
class Category {
/**
* @ORM\Id
* @ORM\Column(type="integer", name="id")
* @ORM\GeneratedValue
*/
protected $id;
// ...
/**
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
*/
protected $children;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* @ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
protected $parent;
public function __construct() {
$this->children = new ArrayCollection();
}
// Once you have that, accessing the parent and children should be straight forward
// (they will be lazy-loaded in this example as soon as you try to access them). IE:
public function getParent() {
return $this->parent;
}
public function getChildren() {
return $this->children;
}
// ...
// always use this to setup a new parent/child relationship
public function addChild(Category $child) {
$this->children[] = $child;
$child->setParent($this);
}
public function setParent(Category $parent) {
$this->parent = $parent;
}
}
答案 1 :(得分:0)
假设您正在尝试实现某种类型的层次结构,如下所示:
array (size=1)
6 =>
array (size=4)
'title' => string 'title6'
'expanded' => boolean true
'folder' => boolean true
'children' =>
array (size=2)
4 =>
array (size=3)
'title' => string 'title4'
'expanded' => boolean true
'folder' => boolean true
3 =>
array (size=4)
'title' => string 'title3'
'expanded' => boolean true
'folder' => boolean true
'children' =>
array (size=1)
2 =>
array (size=3)
'title' => string 'title2'
'expanded' => boolean true
'folder' => boolean true
尝试这样的事情:
public function buildTree($rootCategory, &$tree, $activeCategory = null) {
$tree = ["title" => $rootCategory->getName(),
"expanded" => true,
"folder" => true
];
if ($rootCategory->getId() === $activeCategory)
$tree['active'] = true;
if (count($rootCategory->getChildren()->toArray())) {
foreach ($rootCategory->getChildren() as $child) {
$this->buildTree($child, $tree['children'][$child->getId()], $activeCategory);
}
}
}
你第一次这样称呼它:
buildTree($rootCategory, $tree[$rootCategory->getId()], $activeCategoryId);
其中$rootCategory
是没有父的那个,而$tree
是一个空数组。
基本上,您创建一个void
函数并仅传递构建树的根类别,同时将每个节点添加到$tree
,其中包含整个结构算法完成后
让我知道它是怎么回事。
答案 2 :(得分:0)
private function categoryTree($parent_id = null)
{
$a=array();
$rows = $this->findBy(array('parent' => $parent_id), array('id' => 'ASC'));
foreach ($rows as $row) {
array_push(
$a,
array_filter([
$row->getId() => $row->getName(),
'children' => $this->categoryTree($row->getId())
])
);
}
return $a;
}
答案 3 :(得分:0)
有“教义扩展”项目。它具有 Tree 嵌套行为,可用于解决问题。
URL:https://github.com/Atlantic18/DoctrineExtensions/blob/HEAD//doc/tree.md
Symfony捆绑包:https://symfony.com/doc/master/bundles/StofDoctrineExtensionsBundle/index.html