You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中foreach循环渲染导致收藏按钮重复显示问题

问题原因

当前渲染逻辑没有做状态互斥:页面加载时会无条件给每个商品渲染空心的未收藏按钮,之后循环遍历用户心愿单时,如果商品已被收藏,又会额外追加一个实心已收藏按钮,导致已收藏商品同时显示两个图标。
现有代码还存在几个其他问题:

  • 控制器中残留dd($list)调试语句,会阻断页面正常渲染
  • 循环内给多个表单、按钮、图片设置了重复的id属性,HTML规范要求id全局唯一,重复会引发前端逻辑异常
  • 控制器中$list = Wishlist::all()->where('article_id', $articles->id);属于无效代码:$articles是全量商品的集合对象,不存在id属性,且该变量未在视图中被使用
  • 按钮上重复绑定了onclick="this.form.submit()"事件,按钮本身type="submit"就自带表单提交能力,冗余绑定可能引发重复提交
  • Wishlist模型代码末尾缺少类的闭合大括号,会触发语法错误
修复方案

1. 调整控制器逻辑

删除冗余调试代码和无效变量,直接查询当前用户已收藏的商品id列表,简化视图层判断逻辑:

class FilterController extends Controller
{
    public function catalogus(Request $r)
    {
        $articles = Article::all();
        $categories = Category::all();
        $websites = Website::all();
        // 直接提取当前用户已收藏的商品id数组,判断效率更高
        $wishlistArticleIds = Wishlist::where('user_id', auth()->id())->pluck('article_id')->toArray();
        
        return view('catalogus', compact('articles', 'categories', 'websites', 'wishlistArticleIds'));
    }
}

2. 调整视图渲染逻辑

将两个按钮的并行渲染改为互斥渲染:商品已收藏时只显示实心红心,未收藏时只显示空心红心,同时删除重复id和冗余事件绑定:

<div class="flex flex-col justify-evenly items-center lg:flex-row flex-wrap justify-between gap-y-20 gap-x-2 lg:p-20 lg:w-12/12"> 
    @foreach ($articles as $article)
        <div class="w-8/12 lg:w-3/12 flex flex-col justify-between xl:h-100">
            <form action="{{route('wishlist.store', $article->id)}}" method="post">
                @csrf
                <input name="user_id" type="hidden" value="{{Auth::id()}}" />
                <input name="article_id" type="hidden" value="{{$article->id}}" />
                @if(in_array($article->id, $wishlistArticleIds))
                    <button type="submit">
                        <img src="{{ 'icons/1heart.png' }}" alt="已收藏" width="25">
                    </button>
                @else
                    <button type="submit">
                        <img src="{{ 'icons/0heart.png' }}" alt="未收藏" width="25">
                    </button>
                @endif
            </form>
            <div class="h-2/3 xl:h-1/3 flex justify-center items-center">
                {{-- <img src="{{$article->image}}" alt="" class="h-40"> --}}
            </div>
            <div class="h-20 mt-2">
                <h4 class="text-md text-center flex"><strong>{{ $article->title }}</strong></h4>
            </div>
            <div class="flex flex-row flex-wrap justify-between items-center mt-4">   
                <p class="p-2">{{$article->prijs}}</p> 
                <p>Beschikbaar via {{$article->website->title}}</p>
            </div> 
        </div>   
    @endforeach
</div>

3. 补全模型代码

给Wishlist模型补上末尾缺失的闭合大括号:

class Wishlist extends Model
{
    protected $table = "wishlists";

    protected $fillable = [
        'user_id',
        'article_id',
        'confirmed',
        'available'
    ];

    protected $casts = [
    ];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function article()
    {
        return $this->belongsTo(Article::class);
    }
}
后续优化建议
  • 目前点击收藏会触发整页刷新,体验较差,可后续改为AJAX异步提交,点击后直接本地切换图标状态,无需重载页面
  • 补充取消收藏逻辑:当前点击已收藏的红心仍然走收藏添加路由,会生成重复的收藏数据,需要根据商品收藏状态动态切换表单请求地址和提交逻辑,已收藏状态下点击走删除路由
  • 给收藏表加联合唯一索引,限制同一用户不能重复收藏同一商品,从数据库层面避免脏数据

内容的提问来源于stack exchange,提问作者Stef Verniers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 15:45:39