Это может быть немного запутанным, но я сделаю все возможное, чтобы объяснить, чего я пытаюсь достичь.jQuery: список комментариев исчезает при отправке формы ajax
У меня есть форма комментариев на каждой странице, пользователи могут отправлять комментарии через форму ajax, и представленный комментарий будет отображаться ниже формы без перезагрузки страницы.
Все это работает, пока я не представлю комментарии для показа на основе их post_id
и текущего идентификатора сообщения, который я просматриваю.
Когда я это делаю, каждый пост начнет показывать только его комментарии, но когда я попытаюсь отправить комментарий, comment_list.blade.php
загрузит пустой список комментариев вместо добавления нового комментария к уже существующим. Мне нужно обновить страницу вручную, чтобы увидеть комментарии.
У меня есть 4 представления для замечаний:
- leave_a_comment.blade.php (имеет 2 включает в comment_fields и comment_list)
- comment_fields.blade.php (комментарий форма)
- comment_list .blade.php (список комментариев)
- cancel_reply.blade.php (в закрыть окно ответа)
EDIT: Я думаю, что нашел проблему. в comment.js
функция comment_done_handler()
не возвращает никаких данных.
Так что если я прокомментирую $('.comment-list').html(data.comment_list);
, список комментариев не будет исчезать при новом представлении. Но, конечно, недавно добавленный комментарий не отображается, пока я не перезагружу страницу.
EDIT 2: на самом деле это data.comment_list
, что возвращается пустой в методе comment.js
comment_done_handler (данные).
comment.js
$(document).on('click', 'a.post-this-comment', function(){
var form_data = {
'per_page': $('.comments_per_page').val(),
'commenter_parent': $('#commenter_parent').val(),
'commenter_post': $('#commenter_post').val(),
'commenter_comment': $('#commenter_comment').val(),
'postid': $('#postid').val(),
};
var arr = [
'commenter_parent',
'commenter_post',
'commenter_comment',
'postid'
];
for (var i in arr, i < arr.length, i++) {
var elem = arr[i];
form_data[elem] = $('#' + elem).val();
}
// console.log(form_data); // something like => Object {per_page: "some_value", commenter_parent: "some_value", commenter_user_id: "some_value", commenter_comment: "some_value"}
var request = $.ajax({
type: 'POST',
url: 'post_this_comment',
data: form_data,
dataType: 'json'
});
request.done(comment_done_handler);
request.fail(comment_fail_handler);
});
function comment_done_handler(data){
console.log(data); // data is sent from server
$('.comment-content').append($('.reply-content .comment-fields'));
$('.comment-list').html(data.comment_list); // put new list
$('#captcha-image').attr('src', data.captcha); // put new captchas
clear_input_fields();
remove_error_messages(data);
hide_comment_fields();
}
Comment
Модель
public static function root_comments($postId) {
return self::child_comments(0, 'desc')->where('post_id', $postId);
}
public static function child_comments($parent_id, $order='asc'){
return self::where('parent_id', $parent_id)->orderBy('created_at', $order)->get();
}
public function posts() {
return $this->belongsTo('App\Post');
}
public function user() {
return $this->belongsTo('App\User');
}
CommentController
protected function comment_list($per_page, Request $request, Post $post) {
$postId = $post->id;
$root_comments = Comment::root_comments($postId);
$root_with_replies = $this->include_replies_for($root_comments);
$paginated_comments = $this->paginate($root_with_replies, $per_page, $request);
return $paginated_comments;
}
public function index(Request $request, Post $post){
$view_data = self::view_data($request, $post);
return view('eastgate.comment.leave_a_comment', $view_data);
}
public static function view_data(Request $request, Post $post) {
$instance = new Self;
$per_page = session('per_page')?session('per_page'):config('constants.per_page'); // default per page on opening the comment page
$result['per_page'] = $per_page;
$result['comments'] = $instance->comment_list($per_page, $request, $post);
$result['total_comments'] = $instance->total_comments();
$result['captcha_builder'] = $instance->captcha_builder();
return $result;
}
public function post_this_comment(Request $request, Post $post) {
$comment = new Comment;
$comment->user_id = Auth::id();;
$comment->comment = Input::get('commenter_comment');
$comment->post_id = Input::get('commenter_post');
$comment->parent_id = Input::get('commenter_parent');
if($comment->parent_id > 0){
$my_parent = Comment::find($comment->parent_id);
$comment->parents = $my_parent->parents.'.'.$comment->parent_id;
}else{
$comment->parents = '0';
}
$comment->save();
$per_page = Input::get('per_page');
$comment_list = view('eastgate.comment.comment_list')
->with('comments', $this->comment_list($per_page, $request, $post))
->with('total_comments', $this->total_comments())
->with('per_page', $per_page)
->render();
$response = array(
'status' => 'success',
'msg' => 'Comment Saved!',
'comment_list' => $comment_list,
'captcha' => $this->captcha_builder()->inline()
);
return Response::json($response);
}
comment_fields.blade.php
<div class="comment-fields">
<div class="row commenter-comment">
<div class="form-group col-md-12">
<textarea id="commenter_comment" name="commenter_comment" class="form-control comment-field" title="User's comment" placeholder="Comment Text"></textarea>
</div>
</div>
<div class="row commenter-name-email">
<input type="hidden" id="commenter_parent" name="commenter_parent" class="commenter-parent" value="0">
<input type="hidden" id="commenter_post" name="commenter_post" class="commenter-post" value="{{ $post->id }}">
</div>
<div class="row commenter-captcha">
<div class="col-md-3">
<a href="javascript:void(0)" class="btn btn-success post-this-comment">Comment</a>
</div>
</div>
</div>
comment_list.blade.php
<div class="comment-list">
<div class="row">
<div class="col-xs-12">
<h2>{!! $total_comments !!} comment(s) </h2>
@foreach($comments as $each_comment)
<?php
$name_for_display = $each_comment->user->name;
$date_for_display = $each_comment->created_at->diffForHumans();
$parent_name_for_display = '';
if($each_comment->parent_id > 0){
$parent_comment = $each_comment->parent();
$parent_name_for_display = $parent_comment != null && $parent_comment->name
? $parent_comment->name : 'Anonymous';
$parent_name_for_display = '<span class="glyphicon glyphicon-share-alt" title="Reply to"> </span>'.$parent_name_for_display;
}
$parents_count = substr_count($each_comment->parents, '.');
$offset_length = $parents_count;
$comment_length = 12 - $offset_length;
?>
<div class="col-xs-offset-{!! $offset_length !!} col-xs-{!! $comment_length !!}">
<input type="hidden" id="postid" name="postid" class="post-id" value="{{ $each_comment->post_id }}">
<ul class="list-inline">
<li class="comment-by">{!! $name_for_display !!}</li>
@if($parents_count > 0)
<li class="reply-to">{!! $parent_name_for_display !!}</li>
@endif
<li class="separator"></li>
<li class="comment-on">{!! $date_for_display !!}</li>
</ul>
<p>{!! $each_comment->comment !!}</p>
<a href="javascript:void(0)" class="reply comment{!! $each_comment->id !!}" title="Reply to above comment">Reply</a>
<div class="reply-content reply{!! $each_comment->id !!}"></div>
<hr>
</div>
@endforeach
</div>
</div>
<div class="row">
<div class="col-xs-12">
{!! $comments->render() !!}
</div>
</div>
<div class="row">
<div class="col-xs-12">
Show <input type="text" name="comments_per_page" class="comments_per_page" value="{!! $per_page !!}" size="2" title="Number of comments per page"> comments per page
</div>
</div>
</div>
Пожалуйста, обратите внимание, что если удалить из Comment
модели, она начнет работать и перезагружает правильно comment_list
с вновь добавленным комментарием.
Надеюсь, это имеет смысл и показывает проблему, с которой я сталкиваюсь.
как насчет 'где ('post_id', $ postId) -> get()'; – manix
Это дает ошибку «Отсутствует аргумент 1 для Illuminate \ Support \ Collection :: get(), вызванный в Comment.php' – Halnex
Можете ли вы также отправить метод child_comments? –