[英]jQuery: Comment list disappears on ajax form submission
這可能有點令人困惑,但是我會盡力解釋我要實現的目標。
我在每個帖子頁面上都有一個評論表單,用戶可以通過ajax表單提交評論,並且提交的評論將顯示在表單下方,而無需重新加載頁面。
所有這些都有效,直到我指示評論根據它們的post_id
和我正在查看的當前帖子ID顯示。
當我這樣做時,每個帖子將僅開始顯示其評論,但是當我嘗試提交評論時, comment_list.blade.php
會加載一個空的評論列表,而不是將新評論添加到已經存在的評論中。 我必須手動刷新頁面才能看到評論。
我的評論有4種觀點:
編輯:我認為我發現了問題。 在comment.js
, comment_done_handler()
函數未返回任何數據。
因此,如果我注釋掉$('.comment-list').html(data.comment_list);
評論列表不會在新提交的內容中消失。 但是,當然,在我重新加載頁面之前,看不到新添加的評論。
編輯2:實際上是在comment.js
comment_done_handler(data)方法中返回為空的data.comment_list
。
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
Model中刪除where('post_id', $postId)
,它將開始工作,並使用新添加的評論重新加載正確的comment_list
。
我希望這是有道理的,並顯示出我所面臨的問題。
我沒有嘗試執行代碼,但這是可疑的:
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();
}
root_comments
(在控制器的comment_list
操作中引用)是鏈接child_comments
。 除了child_comments不返回查詢構建器對象之外,它返回一個集合。 您需要從child_comments中刪除get()
調用,而僅在完全構建完查詢后才使用get()
。
另外,請查看查詢范圍 ,這是完成您要嘗試執行的操作的一種更好的方法。
編輯1-示例(使用范圍):
我沒有運行此代碼,因此出現語法錯誤。 這是為了更好地解釋這個概念。
//First, you need to create scopes on the model
public function scopeByParent($query, $parentId, $order = 'asc') {
return $query->where('parent_id', $parentId)->orderBy('created_at', $order);
}
public function scopeForPost($query, $postId) {
return $query->where('post_id', $postId);
}
//Then, change your existing methods...
public static function root_comments($postId) {
return self::byParent(0, 'desc')->forPost($postId)->get();
}
public static function child_comments($parent_id, $order = 'asc') {
return self::byParent($parent_id, $order)->get();
}
現在,這些都將按您的期望返回集合。 當您需要檢索注釋記錄時,可以在其他地方重用這些作用域。
編輯2:
以上是問題的一部分。 問題的第二部分是您永遠不會檢索該評論所針對的帖子。 我在本地進行了更改,並且開始起作用:
public function post_this_comment(Request $request, Post $post) {
//...
$per_page = Input::get('per_page');
//After line 148. The $post that is created by the IoC container is just a reference to the class. You still must load the post from the DB to get the proper data from it.
$post = $post->find($request->commenter_post);
$comment_list = view('eastgate.comment.comment_list')
//...
}
編輯:
嘗試這個:
public static function root_comments($postId) {
return self::child_comments(0, 'desc')->where('post_id', $postId)->get();
}
-編輯前-
您的comment_done_handler
不會獲取新創建的評論列表。 您應該在內部發出另一個ajax請求,或者作為一個單獨的函數
function comment_done_handler(data){
var data = $.ajax({
// ......
// params sent for this request to comment_list controller method
data: {
per_page: 10,
request: request,
post: post_id
},
type: 'GET',
url: 'comment_list'
// ......
}).done(function() {
// ....
}).fail(function(){
// ....
});
console.log(data); // data is retrieved 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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.