我想知道最好的方法是循环遍历 Blade 中包含多种模型类型的 Laravel 集合。以我为例,我有一个包含评论和建议的集合。
ConversationsController
:
$conversation->comments = $conversation->comments->merge($conversation->proposals)->sortBy('created_at');
show.blade.php
:
@foreach($conversation->comments as $collection)
@if(get_class($collection) === 'App\Models\ConversationComment')
@include('partials/comment', ['comment' => $collection])
@else
@include('partials/proposal', ['proposal' => $collection])
@endif
@endforeach
我想出的这个实现是有效的。但感觉有点奇怪。
那么,Laravel 的方法是什么?
我相信您希望将它们合并,因为您想按
created_at
对它们进行排序,然后让它们在列表中混合显示。
尽管这看起来很脏 - 如果你想让它们合并在一起,这是唯一的方法。
有一些代码高尔夫选项可用于此目的,但它们都归结为同一件事。
您可以只使用一个名为
的部分@foreach($conversation->comments as $item)
@include('partials/commentItem', ['item' => $item])
@endforeach
然后让那个部分里面有类似这样的东西:
@if(get_class($item) === 'App\Models\ConversationComment')
@include('partials/comment', ['comment' => $item])
@else
@include('partials/proposal', ['proposal' => $item])
@endif
但是我建议您尝试创建数据传输对象,该对象将封装应为它们显示的所有内容,然后仅使用一个单独的部分来显示它,因为我相信它们共享相同的内容属性。
例如,如果您只想显示评论/提案文本+添加日期+谁留下了该评论/提案,那么您可以将您的评论和提案合并在一起,并以可以以统一形式显示的方式映射它们,例如:
$conversation->comments = $conversation->comments->merge($conversation->proposals)->sortBy('created_at');
$conversation->comments = $conversation->comments->map(function ($value) {
return [
'text' => $value->text,
'created_at' => $value->created_at,
'added_by' => $value->added_by
];
});
然后在你的刀片中,你不必检查他们的班级类型,而只需浏览所有项目并根据需要调用
text
、created_at
和 added_by
。
有关 DTO 的更多详细信息,您可以查看:https://medium.com/@eloufirhatim/what-is-dto-and-how-to-use-it-in-a-laravel-application-7ca1e9045985# :~:text=DTO%20代表%20用于%20数据%20传输,%20的%20部分%20与%20应用程序不同.
或者你可以查看这个库:https://spatie.be/docs/laravel-data/v3/introduction