使用 Ajax 在 Symfony 中无限滚动

Infinite scroll in Symfony using Ajax

我想使用无限滚动显示来自 db 的产品。

这是我的控制器:

    $start=0;
    $limit= 6;

    $query = $repository->createQueryBuilder('classified')
        ->join('classified.statusId','status')
        ->andWhere('status.name=:status')
        ->setParameter('status','active')
        ->setFirstResult($start)
        ->setMaxResults($limit)
        ->getQuery();

      $results = $query->getResult();

    if ($request->isXmlHttpRequest()){

        $list = $this->renderView('search-result.html.twig', [
            'results' => $results
        ]);


    $response = new JsonResponse();
    $response->setData(array('classifiedList' => $list));
    return $response;
}

Ajax:

$(window).scroll(function () {
            if($(window).scrollTop() + $(window).height()>= $(document).height()){
                getmoredata();
            }

        })

        function getmoredata() {
            $.ajax({
                type: "GET",
                url: "{{ path('classified_list', {'type' : 'all'}) }}",
                dataType: "json",
                cache: false,
                success: function (response) {
                        $('.card-deck').append(response.classifiedList);
                        $('#spinner').hide();
                        console.log(response);

                },
                error: function (response) {
                    console.log(response);
                }
            });
        }

所以现在发生的事情是前 6 个结果在触发滚动时重复显示。我知道这是不正确的,我不希望它能正常工作。但我不知道下一步是什么。 那我需要添加分页器什么的吗?

任何帮助将不胜感激,谢谢!

您需要跟踪您的ajax是否在请求,所以当window达到滚动限制时它不会多次请求。此外,您需要跟踪偏移量以及是否有更多数据要加载。例如

 window.__isFetching = false;
 window.__offset = 0;
 window.__hasMoreData = true;

 $(window).scroll(function () {
    if($(window).scrollTop() + $(window).height()>= $(document).height()){

      if(!window.__isFetching && window.__hasMoreData) {
         getmoredata();
      }
    }

 })

 function getmoredata() {
        window.__isFetching = true;
        $.ajax({
            type: "GET",
            // NOTE, you can pass current offset here in url
            url: "{{ path('classified_list', {'type' : 'all', }) }}"+"&offset="+window.__offset,
            dataType: "json",
            cache: false,
            success: function (response) {
                    $('.card-deck').append(response.classifiedList);
                    $('#spinner').hide();
                    console.log(response);

                   // Note that here, server side response must have next offset and hasMoreData attribut.
                    window.__isFetching = false;
                    window.__hasMoreData = response.hasMoreData;
                    window.__offset = response.offset

            },
            error: function (response) {
                console.log(response);
            }
        });
  }

在服务器端,也就是 symfony,你可能想做这样的事情:

// Get offset from request query
$start= $request->query->get('offset');
$limit= 6;

$query = $repository->createQueryBuilder('classified')
    ->join('classified.statusId','status')
    ->andWhere('status.name=:status')
    ->setParameter('status','active')
    ->setFirstResult($start)
    ->setMaxResults($limit)
    ->getQuery();

  $results = $query->getResult();

if ($request->isXmlHttpRequest()){

    $list = $this->renderView('search-result.html.twig', [
        'results' => $results
    ]);


$response = new JsonResponse();
// And add offset and hasMoreData fields in response
$response->setData(array(
  'classifiedList' => $list,
   'offset' => $start += 1
   'hasMoreData' => count($list) < ($limit * &start)
  )
);
return $response;