Laravel循环渲染评论时如何阻止嵌套回复表单提交后重复显示
问题原因
你当前的代码为每一条评论默认渲染了独立的回复表单,所以会出现大量重复表单,同时固定id为reply的回复链接也会存在DOM id重复的异常问题。
解决方案
可根据你的交互需求任选以下两种方案:
方案1:点击回复按钮才显示对应表单(通用交互方案)
默认隐藏所有回复表单,仅点击对应评论的回复按钮时,才显示该评论的回复表单,其余表单保持隐藏。
修改后Blade代码如下:
@foreach($comments as $comment) <div class="display-comment"> <strong>{{ $comment->user->name }}</strong> <p>{{ $comment->comment }}</p> <!-- 回复按钮绑定对应评论ID --> <a href="javascript:void(0)" class="reply-btn" data-comment-id="{{ $comment->id }}">回复</a> <!-- 表单默认隐藏,绑定对应评论ID --> <form method="post" action="{{ route('reply.add') }}" class="reply-form" data-comment-id="{{ $comment->id }}" style="display:none;"> @csrf <div class="form-group"> <input type="text" name="comment" class="form-control" required /> <input type="hidden" name="post_id" value="{{ $post_id }}" /> <input type="hidden" name="comment_id" value="{{ $comment->id }}" /> </div> <div class="form-group"> <input type="submit" class="py-0 btn btn-sm btn-outline-danger" style="font-size: 0.8em;" value="提交回复" /> </div> </form> @include('posts.comments.reply', ['comments' => $comment->replies]) </div> @endforeach <!-- 新增JS控制表单显隐 --> <script> document.querySelectorAll('.reply-btn').forEach(btn => { btn.addEventListener('click', function() { const commentId = this.dataset.commentId; const targetForm = document.querySelector(`.reply-form[data-comment-id="${commentId}"]`); // 切换当前表单显隐,可根据需求新增隐藏其他所有表单的逻辑 targetForm.style.display = targetForm.style.display === 'none' ? 'block' : 'none'; }); // 若使用AJAX无刷新提交,新增提交后隐藏表单逻辑 document.querySelectorAll('.reply-form').forEach(form => { form.addEventListener('submit', function(e) { e.preventDefault(); // 此处填写你的AJAX提交逻辑 // 提交成功后隐藏当前表单 this.style.display = 'none'; }); }) </script>
方案2:单条评论仅允许回复一次,提交后永久隐藏表单
先新增逻辑判断当前登录用户是否已经回复过该评论,仅未回复时才渲染表单。
- 首先给Comment模型新增关联方法,获取当前用户对该评论的回复:
// App/Models/Comment.php public function userReplies() { return $this->hasMany(Comment::class, 'comment_id')->where('user_id', auth()->id()); }
- 修改Blade代码,新增渲染判断条件:
@foreach($comments as $comment) <div class="display-comment"> <strong>{{ $comment->user->name }}</strong> <p>{{ $comment->comment }}</p> <!-- 仅登录且未回复过该评论的用户才显示回复表单 --> @auth @if($comment->userReplies->count() === 0) <a href="" id="reply"></a> <form method="post" action="{{ route('reply.add') }}"> @csrf <div class="form-group"> <input type="text" name="comment" class="form-control" /> <input type="hidden" name="post_id" value="{{ $post_id }}" /> <input type="hidden" name="comment_id" value="{{ $comment->id }}" /> </div> <div class="form-group"> <input type="submit" class="py-0 btn btn-sm btn-outline-danger" style="font-size: 0.8em;" value="Reply" /> </div> </form> @endif @endauth @include('posts.comments.reply', ['comments' => $comment->replies]) </div> @endforeach
注意事项
普通表单提交会触发页面刷新,方案2的判断逻辑会自动生效,无需额外加JS代码。
内容的提问来源于stack exchange,提问作者basic
相关产品推荐
相关产品推荐

