我对刀片递归部分视图有困难。除了comment.blade.php文件中的递归之外,一切都可以正常工作。
我知道我需要在@include('articles.comments.comment', $comment)周围使用一个程序来再次调用自己,但我不知道如何调用它。
article_comments表:
id
message
user_id
parent_id
created_at
updated_atapp\Article.php类:
class Article extends Model {
protected $table = 'articles';
protected $fillable = [
'category',
'title',
'permalink',
'synopsis',
'body',
'source',
'show_author',
'published_at'
];
protected $dates = ['published_at'];
public function scopePublished($query)
{
$query->where('published_at', '<=', Carbon::now());
}
public function setPublishedAtAttribute($date)
{
$this->attributes['published_at'] = Carbon::parse($date);
}
public function comments()
{
return $this->hasMany('App\Comments')->where('parent_id', 0);
}
}app\Comments.php类:
class Comments extends Model {
protected $table = 'article_comments';
protected $fillable = [
'parent_id',
'message',
];
public function author() {
return $this->belongsTo('App\User');
}
public function children()
{
return $this->hasMany('App\Comments', 'parent_id');
}
public function countChildren($node = null)
{
$query = $this->children();
if (!empty($node)) {
$query = $query->where('node', $node);
}
$count = 0;
foreach ($query->get() as $child) {
// Plus 1 to count the direct child
$count += $child->countChildren() + 1;
}
return $count;
}
}app\Http\Controllers\ArticlesController.php
public function show($permalink)
{
$article = Article::where('permalink', '=', $permalink)->with('comments','comments.author','comments.children')->first();
if ($article != null) {
$comments = $article->comments;
return view('articles.show', compact('article','comments'));
} else {
return redirect('/')->with('error', 'This article does not exist.');
}
}resources\views\articles\show.blade.php
@if (count($comments) > 0)
<ul>
@foreach ($comments as $comment)
@include('articles.comments.comment', ['comment'=>$comment])
@endforeach
</ul>
@else
no comments
@endifresources\views\articles\comments\comment.blade.php
<li>
{{ $comment->message }}
@if (count($comment->children) > 0)
<ul>
@foreach ($comment->children as $child)
@include('articles.comments.comment', ['comment'=>$child])
@endforeach
</ul>
@endif
</li>电流错误:
Invalid argument supplied for foreach() (View: /var/www/dev.example.com/resources/views/articles/comments/comment.blade.php) (View: 发布于 2016-01-28 23:50:42
你们关系很好。我认为这应该是可行的:
resources\views\articles\show.blade.php
@if (count($comments) > 0)
<ul>
@each('articles.comments.comment', $comments, 'comment');
</ul>
@else
no comments
@endifresources\views\articles\comments\comment.blade.php
<li>
{{ $comment->message }}
@if (count($comment->children) > 0)
<ul>
@each('articles.comments.comment', $comment->children, 'comment');
</ul>
@endif
</li>app\Http\Controllers\ArticlesController.php:
$article = Article::where('permalink', '=', $permalink)->with('comments','comments.author','comments.children')->first();
$comments = $article->comments;
return view('articles.show', compact('article','comments'));发布于 2016-02-11 01:16:53
首先,我看到您将所有注释放置在一个页面中而不进行任何分页,但是,您将Article模型上的Article方法限制为只有具有parent_id=0的注释才能获得根注释。但是,再看看您的代码,在控制器中,您将缓慢地加载comments.author和comments.children。请注意,延迟加载只会发生在第一个父注释上,然后,所有子节点都必须执行大量查询才能获得它们之间的关系,方法是急切地加载这些关系。
如果您仍然希望将所有注释放在一个页面中,我建议您删除parent_id=0约束并一次性加载这些注释,并应用一种策略对它们进行排序。下面是一个例子:
app\Article.php
class Article extends Model {
// ...
public function comments()
{
return $this->hasMany('App\Comments');
}
}app\Http\Controllers\ArticlesController.php
use Illuminate\Database\Eloquent\Collection;
// ...
public function show($permalink)
{
$article = Article::where('permalink', '=', $permalink)->with('comments','comments.author','comments.children')->first();
if ($article != null) {
$comments = $this->buildCommentTree($article->comments);
return view('articles.show', compact('article','comments'));
} else {
return redirect('/')->with('error', 'This article does not exist.');
}
}
protected function buildCommentTree(Collection $comments, $root = 0)
{
$branch = new Collection();
$comments->each(function(Comment $comment) use ($root) {
if ($comment->parent_id == $root) {
$children = $this->buildCommentTree($comments, $comment->getKey());
$branch->push($comment);
} else {
// This is to guarantee that children is always a Collection and to prevent Eloquent
// from hitting on the database looking for the children
$children = new Collection();
}
$comment->setRelation('children', $children);
});
return $branch;
}现在,我们已经对所有的评论进行了排序,而没有对数据库进行惩罚,我们可以开始遍历广告了。我更喜欢使用两个文件而不是一个进行循环,这样以后我就可以重用代码了。
resources\views\articles\show.blade.php
@if (!$comments->isEmpty())
@include("articles.comments.container", ['comments'=>$comments])
@else
no comments
@endifresources\views\articles\comments\container.blade.php
@if (!$comments->isEmpty())
<ul>
@foreach ($comments as $comment)
@include('articles.comments.show', ['comment'=>$comment])
@endforeach
</ul>
@elseresources\views\articles\comments\show.blade.php
<li>
{{ $comment->message }}
@if (!$comment->children->isEmpty())
@include("articles.comments.container", ['comments'=>$comment->children])
@endif
</li>发布于 2016-02-02 14:41:58
我可能漏掉了什么东西,但在我看来,你的代码太复杂了。例如,您可以在注释模型中添加一个user关系(也可以删除整个count方法):
public function user()
{
return $this->belongsTo('App\User');
}然后,每当您需要访问注释的用户id或用户名时,只需调用:
$user_id = $comment->user->id;
$username = $comment->user->username;那么,您应该能够清理大量的控制器:
$article = Article::where('permalink', '=', $permalink)->first();
$comments = Comments::where('article_id', '=', $article->id)->get();您的show.blade.php文件应该是正常的。您的comment.blade.php文件可以这样编写:
<li>{{ $comment->message }}</li>
@if ($comment->children->count() > 0)
<ul>
@foreach($comment->children as $child)
@include('articles.comments.comment', $child)
@endforeach
</ul>
@endif我相信您对Invalid argument supplied for foreach()错误的问题与您对评论的原始查询有关。错误应该通过使用适当的关系模型来修正。
另外,如果您需要通过一个node列来计算您的评论的子级,您应该可以这样做:
$comment->children()->where('node', $node)->get()->count();https://stackoverflow.com/questions/35073613
复制相似问题