Raz*_*fir 5 php ajax laravel laravel-8
ArticlesController控制器我有这个方法来显示单篇文章及其评论:
class ArticlesController extends FrontendController {
// More code
public function show($slug) {
// Single article
$article = Article::firstWhere('slug', $slug);
$old_article = Article::where('id', '<', $article->id)->orderBy('id', 'DESC')->first();
$new_article = Article::where('id', '>', $article->id)->orderBy('id', 'ASC')->first();
// Comments
$commentsQuery = Comment::where(['article_id' => $article->id, 'approved' => 1])->orderBy('id', 'desc');
$comments = $commentsQuery->paginate(10);
$comments_count = $commentsQuery->count();
return view('themes/' . $this->theme_directory . '/templates/single',
array_merge($this->data, [
'categories' => $this->article_categories,
'article' => $article,
'old_article' => $old_article,
'new_article' => $new_article,
'comments' => $comments,
'comments_count' => $comments_count,
'tagline' => $article->title,
])
);
}
}
Run Code Online (Sandbox Code Playgroud)
在视图中我有这样的评论列表:
<div id="commentsList">
<ol class="commentlist {{ boolval($is_infinitescroll) ? 'infinite-scroll' : '' }}">
@foreach ($comments as $comment)
<li class="depth-1 comment">
<div class="comment__avatar">
<img class="avatar" src="{{ asset('images/avatars/' . $comment->user->avatar) }}" alt="" 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>
<div class="comment__reply">
<a class="comment-reply-link" href="#0">Reply</a>
</div>
</div>
</div>
<div class="comment__text">
<p>{{ $comment->body }}</p>
</div>
</div>
</li>
@endforeach
</ol>
<div class="ajax-load text-center is-hidden">
loading...
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
与文章相关的路线:
// Article routes
Route::get('/', [ArticlesController::class, 'index'])->name('homepage');
Route::get('/category/{category_id}', [ArticlesController::class, 'category'])->name('category');
Route::get('/author/{user_id}', [ArticlesController::class, 'author'])->name('author');
Route::get('/show/{slug}', [ArticlesController::class, 'show'])->name('show');
Run Code Online (Sandbox Code Playgroud)
我想用“无限滚动”替换评论分页。
为此,我有:
/* Infinite comments */
function infiniteComments() {
var page = 1;
$(window).scroll(function() {
if ($(window).scrollTop() + $(window).height() >= $(document).height() - $('.s-footer').height()) {
page++;
loadMoreData(page);
}
});
}
function loadMoreData(page){
var base_url = window.location.href.split('?')[0];
$.ajax({
url: `${base_url}?page=${page}`,
type: "get",
beforeSend: function() {
$('.ajax-load').show();
}
})
.done(function(data) {
if (data.html == "") {
$('.ajax-load').hide();
return;
}
$('.ajax-load').hide();
$(".infinite-scroll").append(data.html);
})
.fail(function(jqXHR, ajaxOptions, thrownError) {
console.log('The server is not responding...');
});
}
$(document).ready(function(){
infiniteComments();
});
Run Code Online (Sandbox Code Playgroud)
当访问https://larablog.com/show/deserunt-qui-exercitationem?page=2正确显示第 2 页上的注释时,Chrome 控制台显示以下500(内部服务器错误)错误:
https://larablog.com/show/deserunt-qui-exercitationem?page=65 500 (Internal Server Error)
The server is not responding...
https://larablog.com/show/deserunt-qui-exercitationem?page=76 500 (Internal Server Error)
The server is not responding...
Run Code Online (Sandbox Code Playgroud)
该错误可以追溯到ArticlesController 中第 70 行的错误消息 - $article = Article::firstWhere('slug', $slug):
试图获取非对象的属性“id”。
这很奇怪,因为没有 Ajax 也$article = Article::firstWhere('slug', $slug) 能正常工作。
这是我的解决方案:
在routes\web.php此新路线中添加了:
Route::post('/load_comments', [ArticlesController::class, 'get_comments_ajax'])->name('load_comments');
Run Code Online (Sandbox Code Playgroud)
在文章控制器中:
/**
* AJAX Call for Loading extra comments
*
* @param Request $request
*
* @return void
*/
public function get_comments_ajax( Request $request ) {
if ( ! $request->ajax() ) {
// Redirect to Home Page or just BOMB OUT!
exit();
}
$more_comments_to_display = TRUE;
/** @todo - 5 - This should\could be a setting */
$article_id = $request->post( 'article_id' );
$page_number = $request->post( 'page' );
$offset = $this->comments_per_page * $page_number;
$data['comments'] = $this->get_commentQuery( $article_id, $this->comments_per_page, $offset )->get();
$content = '';
if ( $data['comments']->count() ) {
$content .= view('themes/' . $this->theme_directory . '/partials/comments-list',
array_merge( $data, [
'is_infinitescroll' => $this->is_infinitescroll
])
);
} else {
$more_comments_to_display = FALSE;
}
echo json_encode( [ 'html' => $content, 'page' => $page_number, 'more_comments_to_display' => $more_comments_to_display, 'article_id' => $article_id ] );
exit();
}
/**
* get_commentQuery
*
* @param int $article_id
* @param int $limit
* @param int $offset
*
* @return object
*/
private function get_commentQuery( int $article_id, int $limit = 0, int $offset = 0 ): object {
$commentQuery = Comment::where( [ 'article_id' => $article_id, 'approved' => 1 ] )->orderBy( 'id', $this->comments_orderby_direction );
if ( $offset > 0 ) {
$commentQuery = $commentQuery->offset( $offset );
}
if ( $limit > 0 ) {
$commentQuery = $commentQuery->limit( $limit );
}
return $commentQuery;
}
Run Code Online (Sandbox Code Playgroud)
如果评论超过 10 条,我只会加载 Ajax 脚本:
@if ($is_infinitescroll && $comments_count > $comments_per_page)
@section('custom_js_files')
<script src="{{ asset('themes/' . $theme_directory . '/js/infinite-comments.js') }}"></script>
@endsection
@endif
Run Code Online (Sandbox Code Playgroud)
$(document).ready(function () {
let flagMoreCommentsToDisplay = true;
let flagCommentsBlockNewRequest = false;
let domInfiniteScroll = $(".infinite-scroll");
infiniteComments();
function infiniteComments() {
let page = 0;
$(window).scroll(function () {
if (flagCommentsBlockNewRequest === false) {
if ($(window).scrollTop() + $(window).height() >= $(document).height() - $('.s-footer').height()) {
if (flagMoreCommentsToDisplay) {
flagCommentsBlockNewRequest = true;
page++;
loadMoreData(page);
}
}
}
});
}
function loadMoreData(page) {
let base_url = window.location.origin
$.ajax({
url: base_url + '/load_comments',
type: 'POST', dataType: 'json',
data: {'_token': token, 'page': page, 'article_id': article_id},
beforeSend: function () {
$('.ajax-load').show();
}
})
.done(function (data) {
$('.ajax-load').hide();
let commentHtml = data.html;
flagMoreCommentsToDisplay = data.more_comments_to_display;
if (flagMoreCommentsToDisplay) {
if (commentHtml !== '') {
domInfiniteScroll.append(commentHtml);
}
}
flagCommentsBlockNewRequest = false;
})
.fail(function () {
flagCommentsBlockNewRequest = false;
});
}
});
Run Code Online (Sandbox Code Playgroud)