首页 > 解决方案 > 在树枝中显示自引用实体

问题描述

我正在尝试使用 Doctrine 的自引用关联来呈现链接树。我有一个像这样的实体:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="link")
 * @ORM\Entity(repositoryClass="App\Repository\LinkRepository")
 */
class Link
{
    /**
     * @ORM\Column(name="link_id", type="integer", nullable=false, options={"unsigned"=true})
         * @ORM\Id()
         * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $linkId;

    /**
     * @ORM\Column(name="name", type="string", length=50)
     */
    private $name;

    /**
     * @ORM\Column(name="url", type="string", length=500)
     */
    private $url;

    /**
     * @ORM\Column(name="parent_id", type="integer")
     */
    private $parentId;

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

    /**
     * @ORM\ManyToOne(targetEntity="Link", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="link_id")
     */
    private $parent;

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

    public function getLinkId(): ?int
    {
        return $this->linkId;
    }

    // Getters and setters ...

    /**
     * @return ArrayCollection
     */
    public function getChildren()
    {
        return $this->children;
    }
}

在我的控制器中,我让它获取链接并调用树枝模板,例如:

public function link(int $linkId, LinkRepository $linkRepository)
{
    $link = $linkRepository->findOneBy(['linkId' => $linkId]);

    return $this->render('link.html.twig',
    [
        'link' => $link
    ]);
}

树枝模板是这样的:

{% extends 'base.html.twig' %}

{% block body %}
    {{ link.name }}

    <h2>Children:</h2>

    {% import _self as macros %}
    <ul>
        <li>{{ link.name }}
            {{ macros.link_tree(link) }}
        </li>

    </ul>
{% endblock %}

{% macro link_tree(link) %}
    {% import _self as macros %}
    <ul>
    {% for linkChild in link.children %}
        <li>
            {{ link.name }}
            {% if linkChild.children %}
                <ul>
                    {{ macros.link_tree(linkChild.children) }}
                </ul>
            {% endif %}
        </li>
    {% endfor %}
    </ul>
{% endmacro %}

虽然当我调用这个控制器时它给了我这个错误:

属性“children”和“children()”、“getchildren()”/“ischildren()”/“haschildren()”或“__call()”方法之一都不存在,并且在“Doctrine\”类中具有公共访问权限ORM\PersistentCollection”。

这似乎是当我在树枝模板中引用 linkChild.children 时。

如何递归循环遍历树枝中的 children()?

标签: symfonydoctrine-ormtwig

解决方案


首先,您的 Doctrine 映射无效:您应该删除该parentId字段,因为您已经添加了与parent字段的适当关联,所以不需要它。

其次,您应该使用 Symfony 的 ParamConverter 来获取控制器内部的链接,如下所示:

public function link(Link $link)

是的,它看起来很简单,您只需在控制器操作中输入链接变量即可获取链接,无需在那里使用 LinkRepository。您可以在此处找到有关 ParamConverter的更多信息。

最后,这似乎是您的数据中的一个问题,因为当您期望 Link 类的实例时,您得到了 Doctrine Collection 的实例。尝试在你的 twig 模板中使用 {{ dump() }} 进行调试,此时没有足够的数据来帮助你进一步解决这个问题。但是您绝对应该先解决映射问题,然后再重试。


推荐阅读