На моем сайте есть статьи, и к этим статьям есть комментарии. У комментариев могут быть дочерние комментарии, а у этих комментариев могут быть дочерние комментарии, которые могут продолжаться практически вечно.
В моей модели 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 делает это довольно хорошо, и для тех, кто не совсем понимает мой вопрос, может помочь это изображение:
Я бы посмотрел на это по-другому: «подсчитать рекурсии» на самом деле просто означает «прощупать глубину этой ветви», поскольку вы действительно имеете дело с односторонним деревом. В этот момент элегантность исчезла, но есть несколько проверенных методов обхода древовидных структур. Вы, вероятно, захотите обход в глубину и подсчет по пути. en.wikipedia.org/wiki/Поиск в глубину






Судя по всему, в шаблонах 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-переменная
Вы пытаетесь сделать это в представлении или контроллере?