我目前正在使用一个自引用实体,我必须基于该实体构建一个小列表结构(<ul><li>
(。但是,该列表必须考虑深度,因此我需要使用父/子关系作为渲染器的基础。这是原始实体:
<?php
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity()
* @ORMTable(name="categories")
*/
class Category
{
/**
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
* @ORMColumn(type="integer")
*/
protected $id;
/**
* @ORMColumn(type="string", length=255)
*/
protected $name;
/**
* @var Category
*
* @ORMManyToOne(targetEntity="Category", inversedBy="children")
* @ORMJoinColumn(name="category_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
*/
protected $parent;
/**
* @var Collection
*
* @ORMOneToMany(
* targetEntity="Category",
* mappedBy="parent",
* cascade={"ALL"}
* )
*/
protected $children;
public function __construct()
{
$this->children = new ArrayCollection();
}
public function getId():
{
return $this->id;
}
public function setId(int $id)
{
$this->id = $id;
}
public function getName()
{
return $this->name;
}
public function setName(string $name)
{
$this->name = $name;
}
public function getParent()
{
return $this->parent;
}
public function setParent(Category $parent)
{
$this->parent = $parent;
}
public function setChildren(array $children)
{
$this->children = $children;
}
public function getChildren()
{
return $this->children;
}
public function addChild(Category $category)
{
if (!$this->children->contains($category)) {
$category->setParent($this);
$this->children->add($category);
}
}
public function removeChild(Category $category)
{
if ($this->children->contains($category)) {
$this->children->removeElement($category);
}
}
}
受此启发,我实现了一个非常幼稚的实现:https://wildlyinaccurate.com/simple-nested-sets-in-doctrine-2/
但是,这种基于深度的填充逻辑对我<ul><li>
结构没有帮助。有没有人推荐任何将自引用对象呈现为 HTML 列表的方法?
以下是打印
出 3 级无序类别列表 (( 的树的方法:
<?php $rootCategories = $em->getRepository('EntityCategory')->findBy(['parent' => null]) ?>
// Root categories container
<ul>
<?php foreach ($rootCategories as $rootCategory): ?>
<li>
<?= $rootCategory->getName() ?>
<?php if ($rootCategory->getChildren()): ?>
// First child categories container
<ul>
<?php foreach ($rootCategory->getChildren() as $firstChildCategory): ?>
<li>
<?= $firstChildCategory->getName() ?>
<?php if ($firstChildCategory->getChildren()): ?>
// Second child categories container
<ul>
<?php foreach ($firstChildCategory->getChildren() as $secondChildCategory): ?>
<li><?= $secondChildCategory->getName() ?></li>
<?php endforeach ?>
</ul>
<?php endif ?>
</li>
<?php endforeach ?>
</ul>
<?php endif ?>
</li>
<?php endforeach ?>
</ul>