Отображение сущности, ссылающейся на себя в ветке - PullRequest
0 голосов
/ 25 мая 2019

Я пытаюсь отобразить дерево ссылок, используя ассоциативную ссылку 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 () в ветке?

Ответы [ 2 ]

1 голос
/ 25 мая 2019

Прежде всего ваше отображение Doctrine недопустимо: вы должны удалить поле parentId, в этом нет необходимости, поскольку вы уже добавили соответствующую связь с полем parent.

Во-вторых, вы должны использовать ParamConverter Symfony, чтобы получить ссылку внутри контроллера следующим образом:

public function link(Link $link)

Да, это так просто, как кажется, вы можете получить ссылку, просто напечатав переменную ссылки в действии вашего контроллера, нет необходимости использовать LinkRepository там. Вы можете найти больше информации о ParamConverter здесь .

Наконец, кажется, что проблема в ваших данных, потому что у вас есть экземпляр Doctrine Collection, когда вы ожидаете экземпляр класса Link. Попробуйте выполнить отладку, используя {{dump ()}} внутри вашего шаблона ветки, на данный момент недостаточно данных, чтобы помочь вам в этом. Но вам определенно следует сначала исправить проблему с отображением, прежде чем пытаться снова.

0 голосов
/ 27 мая 2019

Получается, что я отправлял неправильную вещь в макрос, ожидал linkChild, и я передавал linkChild.children.Внутри макроса он пытался сослаться на linkChild.children.children

Это было исправлено с помощью:

{{ link.name }}
{% if linkChild.children %}
  <ul>
    {{ macros.link_tree(linkChild) }}
  </ul>
{% endif %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...