我在 Laravel 8 中制作了一个博客应用程序。
文章支持评论和评论回复。我目前正在开发更新评论功能。
在评论模型中,我像这样“合并”评论和回复:
public function replies() {
return $this->hasMany(Comment::class, 'parent_id');
}
在控制器中,我有:
public function update_comment(Request $request, $id) {
$comment = Comment::find($id);
if ($comment->user_id === auth()->user()->id) {
$comment->body = $request->get('msg');
$comment->save();
if ($request->expectsJson()) {
return response()->json([
'status' => 'success',
'message' => 'The comment was updated.'
]);
} else {
return redirect()->back()->with('success', 'The comment was updated.');
}
}
}
该应用程序支持主题,因此上述代码必须在有或没有 AJAX 的情况下工作。确实如此。
在
comments-list.blade.php
我有:
@foreach ($comments as $comment)
@if (null == $comment->parent_id)
<li class="depth-1 comment">
<div class="comment__avatar">
<img class="avatar" src="{{ asset('images/avatars/' . $comment->user->avatar) }}"
alt="{{ $comment->user->first_name }} {{ $comment->user->last_name }}" width="50" height="50">
</div>
<div class="comment__content">
<div class="comment__info">
<div class="comment__author">{{ $comment->user->first_name }} {{ $comment->user->last_name }}</div>
<div class="comment__meta">
<div class="comment__time">{{ date('jS M Y', strtotime($comment->created_at)) }}</div>
@auth
<div class="comment__reply">
@if ($comment->user->id !== Auth::user()->id)
<a class="comment-reply-link" href="#0">
<i class="fa fa-comment"></i> Reply
</a>
@endif
@if ($comment->user->id == Auth::user()->id)
<a href="#0" class="comment-edit-link">
<i class="fa fa-edit"></i> Edit
</a>
@include(
'themes/' . $theme_directory . '/partials/comment-delete-form',
['commentOrReply' => $comment]
)
@endif
</div>
@endauth
</div>
</div>
<div class="comment__text">
<p>{{ $comment->body }}</p>
</div>
</div>
@auth
@include('themes/' . $theme_directory . '/partials/comment-form')
@if ($comment->user->id == Auth::user()->id)
@include('themes/' . $theme_directory . '/partials/comment-edit-form', [
'commentOrReply' => $comment,
])
@endif
@endauth
{{-- Comment replies --}}
@if (count($comment->replies))
<ul class="children">
@foreach ($comment->replies as $reply)
<li class="depth-2 comment">
<div class="comment__avatar">
<img class="avatar" src="{{ asset('images/avatars/' . $reply->user->avatar) }}"
alt="{{ $comment->user->first_name }} {{ $comment->user->last_name }}"
width="50" height="50">
</div>
<div class="comment__content">
<div class="comment__info">
<div class="comment__author">{{ $reply->user->first_name }}
{{ $reply->user->last_name }}</div>
<div class="comment__meta">
<div class="comment__time">{{ date('jS M Y', strtotime($reply->created_at)) }}
</div>
@auth
<div class="comment__reply">
@if ($reply->user->id == Auth::user()->id)
<a href="#0" class="comment-edit-link">
<i class="fa fa-edit"></i> Edit
</a>
@include(
'themes/' .
$theme_directory .
'/partials/comment-delete-form',
['commentOrReply' => $reply]
)
@endif
</div>
@endauth
</div>
</div>
<div class="comment__text">
<p>{{ $reply->body }}</p>
</div>
</div>
@auth
@if ($reply->user->id == Auth::user()->id)
@include('themes/' . $theme_directory . '/partials/comment-edit-form', [
'commentOrReply' => $reply,
])
@endif
@endauth
</li>
@endforeach
</ul>
@endif
</li>
@endif
@endforeach
我使用相同的模板来编辑*评论&和评论回复:
<div class="h-text-center alert-box-ajax alert-box alert-box--success">
The comment was updated. Refresh the page to see the changes.
</div>
<form class="commentEditForm" method="post" action="{{ route('comment.update', $commentOrReply->id) }}" autocomplete="off" novalidate>
@csrf
<fieldset>
<div class="message form-field">
<textarea name="msg" id="message" class="h-full-width" placeholder="Your Message" required>{{ $commentOrReply->body }}</textarea>
@error('msg')
<p class="help-block text-danger">{{ $message }}</p>
@enderror
</div>
<br>
<input name="submit" id="submit" class="btn btn--primary btn-wide btn--large h-full-width" value="Update Comment" type="submit">
</fieldset>
</form>
</div>
我使用以下代码来更新(和添加)评论和评论回复:
// Add/Edit comment
$(document).on('submit', '.commentForm, .commentEditForm', function (event) {
event.preventDefault();
var form = $(this);
form.validate({
errorElement: "p",
errorClass: "help-block text-danger",
rules: {
msg: "required",
},
messages: {
msg: "Enter a comment",
}
});
// Check if the form is valid
if (!form.valid()) {
return;
}
var $fields = form.find("textarea"),
url = form.attr("action"),
data = form.serialize();
$.ajax({
dataType: "json",
type: "post",
url: url,
data: data,
cache: false,
success: function (response) {
if (response.status === 'success') {
form.closest(".form-wrapper").find(".alert-box--success").slideDown(250).delay(2500).slideUp(250)
.slideDown(250)
.delay(2500)
.slideUp(250);
$fields.val("");
if (form.hasClass('commentEditForm')) {
form.slideUp();
form.closest(".depth-1").find(".comment__text").slideDown();
}
} else {
form.closest(".form-wrapper").find(".alert-box--error").slideDown(250).delay(2500).slideUp(250)
.slideDown(250)
.delay(2500)
.slideUp(250);
}
},
error: function (err) {
console.log(err);
},
});
});
我的目标是让评论(或回复)更新立即在页面上可见,无需刷新页面。
怎样才能达到想要的效果?
您必须添加以下步骤:
-1-从控制器返回更新后的评论正文
-2-在 $.ajax 的成功部分中,您获得评论并更新内容(看起来您没有在 html 中使用 id='comment-id' 或类似的内容,但您需要知道在哪里更新评论)
第一步如下:
public function update_comment(Request $request, $id) {
$comment = Comment::find($id);
//you may add validation here
if ($comment->user_id === auth()->user()->id) {
$comment->body = $request->get('msg');
$comment->save();
if ($request->expectsJson()) {
return response()->json([
'status' => 'success',
'message' => 'The comment was updated.'
//updated comment here
'body'=>$request->get('msg');
]);
} else {
return redirect()->back()->with('success', 'The comment was updated.');
}
}
}
下面第二部分仅展示评论中更新的地方:
$.ajax({
dataType: "json",
type: "post",
url: url,
data: data,
cache: false,
success: function (response) {
if (response.status === 'success') {
//here add code to get the place to update the comment (usually done by id but you may use another method)
form.closest(".form-wrapper").find(".alert-box--success").slideDown(250).delay(2500).slideUp(250)
.slideDown(250)
.delay(2500)
.slideUp(250);
$fields.val("");
if (form.hasClass('commentEditForm')) {
form.slideUp();
form.closest(".depth-1").find(".comment__text").slideDown();
}
} else {
//...
//...