使用Laravel实现AJAX分页

15

我有一个名为posts.blade.php的视图,它被包含在home.blade.php中:

<div id="posts">
    @foreach ($posts as $post)
        <div class="list-item clearfix">
            <div class="content">
                <img src="{{ URL::to($post->thumbnail) }}" alt="" />
                <h1>{{{ $post->title }}}</h1>
            </div>
            <div class="score">{{ $post->rating }}</div>
        </div>
    @endforeach
    <div id="pagination">{{{ $posts->links() }}}</div>
</div>

当用户搜索某些帖子时,控制器的postSearch()函数将返回JSON响应:
function postSearch() 
{
    $posts = $posts->select(...)->where(...)->orderBy(...)->paginate(5); //Search posts

    return Response::json(View::make('includes.posts', ['posts' => $posts])->render());
}

而 jQuery 将 HTML 追加到 #posts div 上:

$('#search').submit(function(e) {
    e.preventDefault();
    var form = $(this);

    $.post(form.attr('action'), form.serialize(), function(data) {
        $('#posts').html(data);
    });
});

这个功能很完美。但是,当我点击分页链接时,页面会重新加载,我的搜索结果也会消失(显而易见)。如何分页这些帖子?我阅读了这个这个这篇文章,但我不知道如何实现它。 编辑 这是到目前为止的分页jQuery代码:
$('#posts').on('click', '.pagination a', function(e) {
    e.preventDefault();
    var url = $(this).attr('href'),
        page = url.split('page=')[1],
        data = $('#search').serializeArray();

    data.push({page: page}); // Add page variable to post data
    console.log(data);

    $.post($('#search').attr('action'), data, function(data) {
        $('#posts').html(data['posts']);
    });
});

当我点击分页链接 (第2页) 时,将发送这些数据:

在此输入图片描述

不幸的是,什么都没有发生,仍然显示第1页的帖子。

4个回答

16

我对 Laravel 中的分页不是很熟悉,但从你列出的链接来看,它似乎不是太难。不过这段代码未经测试……

$('#pagination a').on('click', function(e){
    e.preventDefault();
    var url = $(this).attr('href');
    $.post(url, $('#search').serialize(), function(data){
        $('#posts').html(data);
    });
});

更新

如果分页链接出现错误(例如原帖中的情况),您需要自行构建URL。
只需取出您想要的URL并在其后添加?page=#number即可。

// page being the page number stripped from the original link
var url = $('#search').attr('action')+'?page='+page;

请查看我的编辑。我尝试了你的代码,但它返回了我的主页的 HTML,因为分页链接的 href 是 http://localhost:8080/laravel/laravel/public?page=2 - JasonK
1
尝试通过GET方式发送页面编号。我进行了一些测试,看起来Laravel无法获取POST参数。只需将其附加到操作URL即可:$('#search').attr('action')+'?page='+page - lukasgeiter
让我指出,if ($(this).attr('href') == '#') 检查是不必要的,因为当前的分页链接是不可点击的。 - JasonK
谢谢,已经移除了...可能在框架的早期版本中它是可点击的。 - lukasgeiter

2
我有一个完美的工具可以完成这项工作。请查看这个仓库:https://github.com/themightysapien/ajaxtable
请阅读文档,它非常易于使用,专门为Laravel设计。您只需要按照以下示例返回结果即可。
return Response::json(array(
              'data'=> View::make('only_table_row_view', compact('collection')->render(),
              'pagination'=>(string) $collection->links()
              ));

需要添加必要的文件

<link rel="stylesheet" href="css/ajaxtable.css">
<script src="js/plugins.js"></script>
$(".yourtable").ajaxtable();

通过在表格中使用 data-requestUrl 属性初始化您的ajax url。 在您希望出现分页的页面中添加一个名为 id="paginationWrapper" 的 div。

如果遇到任何问题,请在本地服务器上运行存储库,并查看html标记和插件选项的源代码。


2

我正在使用以下js代码来在点击href时获取数据。

// Your Local url 
var Url = 'laraveltestproject/laravelpagination';

$('#ajaxContent').load("Url");

$('.pagination a').on('click', function(event) {

    event.preventDefault();
    if ($(this).attr('href') != '#') {
        $('#ajaxContent').load($(this).attr('href'));
    }
});

完整的示例可以访问http://www.tutsway.com/laravel-ajax-pagination-example.php


1

博客中发布文章的示例,解决删除按钮重新加载分页问题: (简单的foreach循环,但您必须为面板和按钮提供一个id,并为按钮使用一个类,并使用$post->id来定义所有内容)

最后的诀窍是不调用使用pagination()的视图/控制器,而是使用javascript更改所需的视图。

      @foreach($posts as $post)
    <div id="panel{{$post->id}}" class="panel panel-default">
      <div class="panel-body">
        {!! $post->content !!}
      </div>
      <div class="panel-footer">
        <span class="label label-default"><span class="glyphicon glyphicon-time"></span> creado {{$post->created_at->diffForHumans()}}</span>
        <span class="label label-default"><span class="glyphicon glyphicon-time"></span> modificado {{$post->updated_at->diffForHumans()}}</span>
        <span class="label label-success">autor: {{ imagica\User::find($post->user_id)->name}}</span>
        @if(Auth::user()->id === $post->user_id)

          <form method="post" style="position:relative; top:-25px;">
            <button class="btn btn-danger btn-sm pull-right destroy" id="{{$post->id}}" type="button" >eliminar</button>
          </form>

          <form action="{{ action('PostsController@edit', $post->id) }}" method="get" style="position:relative; top:-25px;">
            <button class="btn btn-warning btn-sm pull-right" type="submit" >Editar</button>
            {{-- {{ csrf_field() }} --}}
          </form>
        @endif
      </div>
    </div>
  @endforeach

在查看JavaScript的最后:
$(function(){
$(".destroy").on("click", function(){
  var vid = $(this).attr("id");
  var v_token = "{{csrf_token()}}";
  var parametros = {_method: 'DELETE', _token: v_token};
  var archivo = "http://imagica.app/posts/" + vid + "";
  $.ajax({
     type: "POST",
     url: archivo,
     data: parametros,
     success: function(data){
       $('#panel'+ data).hide();
       location.reload();
     }
  });
});
});

在控制器的destroy函数中(注意,你将$post->id作为数据发送到ajax,它用于定义选择器来隐藏你删除的帖子的面板):
    public function destroy($id)
{
  $post= Post::find($id);
  $article_id= $post->article_id;
  $article= Article::find($article_id);
  $msg = session()->flash('message', "Post eliminado.");
  $post-> delete();
  $data= $post->id;
  return $data;
}

在JavaScript中,"location.reload()"函数用于刷新页面以加载Flash消息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接