这可能有点令人困惑,但我会尽力解释我想要实现的目标。
我在每个帖子页面都有一个评论表单,用户可以通过ajax表单提交评论,提交的评论将显示在表单下方,无需重新加载页面。
所有这一切都有效,直到我根据他们的post_id
和我正在查看的当前帖子ID指示评论显示。
当我这样做时,每个帖子都会开始只显示其评论,但当我尝试提交评论时,comment_list.blade.php
会加载一个空的评论列表,而不是将新评论添加到现有评论中。我必须手动刷新页面才能看到评论。
我对评论有4个观点:
编辑:我认为我发现了问题。在comment.js
comment_done_handler()
函数中没有返回任何数据。
因此,如果我评论$('.comment-list').html(data.comment_list);
,则评论列表在新提交时不会消失。但当然,在我重新加载页面之前,新添加的评论是不可见的。
编辑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>
请注意,如果我从where('post_id', $postId)
模型中移除Comment
,它将开始工作,并使用新添加的评论重新加载正确的comment_list
。
我希望这是有道理的,并表明我面临的问题。
答案 0 :(得分:1)
我没有尝试执行代码,但这是可疑的:
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()
。
另外,查看query scopes,这是一种更好的方式来完成你想要做的事情。
编辑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')
//...
}
答案 1 :(得分:0)
修改强>
试试这个:
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();
}