Как ограничить рекурсии? - Ларавель/Блэйд

На моем сайте есть статьи, и к этим статьям есть комментарии. У комментариев могут быть дочерние комментарии, а у этих комментариев могут быть дочерние комментарии, которые могут продолжаться практически вечно.

В моей модели Comment.php дочерние комментарии организованы через отношение hasMany:

public function children() {
    return $this->hasMany('App\Comment','parent_id');
}   

В моем контроллере я получаю комментарии, у которых нет родителя, например:

$comments = Comment::where('submission_id', $submission->id)->where('parent_id', NULL)->get();

а затем я foreach их в режиме лезвия:

<div class = "comment-thread-container">
@foreach ($comments as $comment)
    @include('partials.comment_block')  
@endforeach
</div>

Что включено, так это подвид под названием comment-block.blade.php, который вызывается для каждого комментария.

Внутри этого подпредставления находится ДРУГОЙ foreach, который вызывает дочерние элементы этого комментария:

@foreach ($comment->children as $comment)
<div style = "margin-left: 8px">
    @include('partials.comment_block')
</div>
@endforeach

По сути, это может продолжаться вечно. Однако я этого не хочу.

Я хочу сделать так, чтобы, например, если у комментария было 10 поколений родителей (то есть у комментария будет дочерний элемент, а у этого комментария будет дочерний элемент и т. д. и т. д. 10 раз), он останавливался и показывал ссылка с чем-то вроде «Показать всю ветку», которая будет ссылаться на его собственную страницу.

Однако я не знаю, как я мог это сделать. Какой был бы самый элегантный способ подсчета рекурсий?

Reddit делает это довольно хорошо, и для тех, кто не совсем понимает мой вопрос, может помочь это изображение:

Как ограничить рекурсии? - Ларавель/Блэйд

Вы пытаетесь сделать это в представлении или контроллере?

bluemoon6790 16.07.2019 23:07

Я бы посмотрел на это по-другому: «подсчитать рекурсии» на самом деле просто означает «прощупать глубину этой ветви», поскольку вы действительно имеете дело с односторонним деревом. В этот момент элегантность исчезла, но есть несколько проверенных методов обхода древовидных структур. Вы, вероятно, захотите обход в глубину и подсчет по пути. en.wikipedia.org/wiki/Поиск в глубину

parttimeturtle 16.07.2019 23:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
4
2
499
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Судя по всему, в шаблонах Blade переменная $loop автоматически создается в каждом операторе @foreach.

Одно из многих свойств этой переменной — $loop->depth.

Это будет подсчитывать уровень вложенности текущего цикла.

Так что в моем случае, когда вложенный цикл достигает 10, я просто @break рекурсию.

@foreach ($comment->children as $comment)
    @if ($loop->depth == 10)
        @include('partials.comment_end')
        @break
    @else
        <div style = "margin-left: 8px">
            @include('partials.comment_block')
        </div>
    @endif
@endforeach

Документация здесь: https://laravel.com/docs/5.8/blade#the-loop-переменная

Другие вопросы по теме