2013-10-22 2 views
3

내 프로젝트에 무한 아약스 스크롤 플러그인을 구현했습니다 (https://github.com/webcreate/infinite-ajax-scroll). div의 긴 목록을 표시하는 PHP 프로젝트입니다. 무한 스크롤은 서버 측 페이지 매김을 사용합니다. 또한 서버 측 필터링 및 순서 지정이 필요하며 이상적으로 Ajax를 사용하여 무한의 스크롤과 잘 작동하도록하고 싶습니다. Ajax를 사용하여 필터를 전달하는 방법은 무엇입니까? JQuery를 사용하여 필터링하는 방법에 대한 자습서를 찾았으나 PHP를 사용하는 튜토리얼은 없습니다.Ajax와 무한 스크롤로 서버 사이드 (PHP) 필터링 및 순서 지정

나는 필터링과 무한 스크롤링 기능을 모두 가지고 있지만, 좋은 플러그인처럼 보이기 때문에 두 가지를 함께 사용하지 말라고 권고하는 문서에서 발견되었습니다.

누구든지 내 접근 방식에 대해 조언 할 수 있습니까? 새로운 필터를 선택하면 무한 스크롤을 재설정해야합니다. 하지만 어떻게하면 좋을까요? 선택한 필터를 무한 스크롤로 전달하는 방법은 무엇입니까?

아래는 제가 지금까지 가지고있는 것입니다.

$cat = (isset($_GET['cat']) ? urldecode($_GET['cat']) : ''); 
    $page = (int) (!isset($_GET['p'])) ? 1 : $_GET['p']; 
    $start = ($page * $pagelimit) - $pagelimit; 
    $limit = $pagelimit*$page; 

    //get total number of discounts for search 
    $total_items = Stuff::countItems($cat); 

    if($total_items > ($page * $limit)){ 
     $next = ++$page; 
    } 

    //get items 
$items = Stuff::getItems($cat, $sortby, $dir, $start, $limit); 

if(!$items){ 
    header('HTTP/1.0 404 Not Found'); 
    echo 'Page not found!'; 
    exit(); 
} 

?> 
<html> 
    <head> 
     <title></title> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 
     <script type="text/javascript" src="js/jquery-ias.min.js"></script> 
     <script type="text/javascript"> 
      $(document).ready(function() { 
      // Infinite Ajax Scroll configuration 
      jQuery.ias({ 
       container : '.wrap', // main container where data goes to append 
       item: '.item', // single items 
       pagination: '.paginate', // page navigation 
       next: '.paginate a', // next page selector 
       loader: '<img src="css/ajax-loader.gif"/>', // loading gif 
       noneleft: 'No more items', //Contains the message to be displayed when there are no more pages left to load 
       triggerPageThreshold: 5, // show "load more" if scroll more than this to stop 
       trigger: "Load more items" 
      }); 
      }); 
     </script> 
    </head> 
    <body> 
    <div class="wrap">  
     <?php 
     echo 'TOTAL: '.$total_items .'<br />'; 

     //filter through categories*/ 
     echo 'FILTER BY CATEGORY:'; 
     foreach ($categories as $category){ 
      $categoryURL = urlencode($category); 
      echo "<a href=\"index.php?cat=$categoryURL\">$category<a/> | "; 
     }  
     //loop through and display items 
     foreach ($items as $id => $item){ 

      echo "<div style=\"border:1px solid green;margin-bottom:5px;\" class=\"item\" id=\"item-$id\"> 
        ID: $id <br /> 
        $item[name]<br />                                                         
        $item[cat]<br /> 
        $item[description]<br /> 
      </div>"; 
     } 
     ?> 
    <!--paginagation--> 
    <?php if (isset($next)): ?> 
    <div class="paginate"> 
     <a href='index.php?cat=<?php echo $cat?>&p=<?php echo $next?>'>Next</a> 
    </div> 
    <?php endif?> 
    </div> 
    </body> 
</html> 
+0

그래서 html/javascript를 사용하여 필터를 지정하고 AJAX를 통해 서버 측 스크립트에 제출하려는 경우, 올바르게 입력 했습니까? 그렇다면 어떤 종류의 필터입니까? – Ch33f

+0

나는 또한이 부분이 당신을 위해 작동하지 않는 부분을 파악하려고합니다. 카테고리가 필터링되어야합니다 - 일어나지 않아야하는 것은 무엇입니까? –

+0

예, 범주가 필터링되지만 페이지를 다시로드 한 후에 만 ​​적용됩니다. 필터를 적용 할 때 아약스 사용하여 새 결과를로드하려면 노력하고있어. 그러면 아마 무한 스크롤을 재설정해야 할 것입니다. 그런 다음 선택한 필터 (카테고리)를 전달하여 무한 스크롤이 선택한 필터와 작동하도록해야합니다. 희망을 분명히 해줍니다. – LeeTee

답변

3

무한 스크롤 및 필터링은 클라이언트 (이미로드 된 데이터의 경우)와 서버 (이후의 페이지로드의 경우) 모두에 필터를 적용하는 경우에만 의미가 있습니다.

그러나 완전히 다른 필터 나 정렬을 적용한 후에는 사용자가 첫 번째 페이지로 돌아오고 싶다고 생각할 것입니다 (또는 무한 스크롤의 경우 맨 위로 스크롤). 이미로드 된 일부 결과가 손실되는 유일한 방법입니다. 당신은 아마도 cache 그 결과가 조금 더 빨라질 수 있습니다.

KnockoutJS 또는 유사한 클라이언트 측 MVC 라이브러리를 사용하기 시작하는 것이 좋습니다. jQuery는 많은 복잡성에 유용합니다. 어떤 시점에서 당신은 뭔가 더 좋은 것이 필요하다는 것을 알게됩니다.

Here's a cleaned up extract 나는 얼마 전에 비슷한 앱이 필요했습니다. (edit link)

'페이지'매개 변수는 전혀 필요하지 않습니다. 내 "가짜"공급자가 순차적이고 읽기 쉬운 이름을 반환 할 수 있도록 사용했습니다.

서버 측에서는 현재 쿼리에 대해 클라이언트에게 보낸 결과의 수 (언제든지 $_SESSION)를 알아야합니다. 이 같은

뭔가 :

function getResults($query) { 
    if($_SESSION['query']['category'] !== $query['category']) { 
     if(!array_key_exists($query['category'], $_SESSION['resultsSent'])) { 
      $_SESSION['resultsSent'][$query['category']] = 0; 
     } 
     $_SESSION['query'] = $query; 
    } 

    $sql = 'SELECT * FROM foo WHERE category = ? LIMIT ?, ?'; 
    $data = $db->select($sql, array($_SESSION['query']['category'], $_SESSION['resultsSent'][$query['category']], 10); 

    $_SESSION['resultsSent'][$query['category']] += count($data); 

    return json_encode($data); 
} 

if(!array_key_exists('query', $_SESSION)) { 
    $_SESSION['resultsSent'] = array(); 
    $_SESSION['query'] = array(); // maybe some defaults here? 
} 

if(array_key_exists('query', $_POST)) { 
    echo getResults($_POST['query']); 
} 

당신은 AJAX 호출을 수행하는 resultsService를 작성해야합니다. 이 같은 아마 뭔가 :

function resultsService() { 
    this.query = function(query, success) { 
     jQuery.post({ 
      url: 'index.php', 
      data: query, 
      success: success 
     }); 
    } 
} 

당신이 정상에 당신의 무한 스크롤 라이브러리를 때리고있다해야 할 모든 후.

이것은 (1) 클라이언트에서 이미로드 된 데이터를 제거하지 않고 현재 필터에 맞지 않는 경우 숨기고 (2) 가능한 모든 필터 조합에 대해 서버가 얼마나 많은 데이터를 알고 있는지에 따라 달라집니다 그것은 그것을 다시 돌려 보내지 않도록 보냈습니다.

당신은 배타적이지 결과 더 복잡한 필터가있는 경우 (하나 개의 결과가 여러 필터 조합에 대해 반환 될 수 있습니다 - 생각 가격, 평가 객실하지 카테고리수) 당신 ' 결국 클라이언트에 중복을 보냅니다. 전체 목록을 재설정하는 것 이외에는 실제 해결책이 없습니다. 개수뿐만 아니라 클라이언트에 보낸 모든 개별 결과를 추적하고 쿼리하는 동안 (WHERE id NOT IN (1, 2, 17, 20, ...))이를 필터링 할 수 있지만 대용량 데이터에는 효과가 없습니다.

정렬을 위해 클라이언트에게 보낸 내용을 정확히 알고 있거나 분명히 목록을 재설정하는 것 이외의 다른 해결책은 없습니다.

저는 JSON 인코딩 된 문자열 (ko.toJS (this.query))로 JS 객체를 입력 한 다음 PHP에서 json_decode을 입력합니다. 입니다. 아무리 당신이 그 JS 개체를 만들었더라도 JSON으로 보내면 직접 수동으로 GET 매개 변수로 직렬화하는 것보다 낫습니다.

또한 모든 필터 유형에 공통 형식을 사용하고 서버 측 설정 패턴으로 처리하는 것이 가장 좋습니다.

['category': 1, 'subcategory':2, 'user': 1234]를 들어 내가 categoryFilter, subcategoryFilteruserFilter를 정의하는 것, 각각에 대해 여기에 비트를 추가 call_user_func를 사용하여 전화 조회를 따라 매개 변수로 필터링 된 값을 전달합니다.

실제 코드가 어떻게 보이고 사용자가 SQL 쿼리를 작성할 수 있는지는 사용중인 항목에 따라 다릅니다. 위에서 사용한 DB 클래스는 Laravel 번들입니다.

클라이언트 측 건물에서 쿼리 객체는 기본 jQuery로도 어렵지 않아야합니다.

+0

깊이있는 답변을 주셔서 감사합니다. 나는 이것에 대해 많은 연구를 해왔으며 Knockout을 사용하기 시작하기 위해 모든 것을 바꾸고 싶지는 않지만, 제안을 주신 덕분에 앞으로이 문제를 조사 할 것입니다. 새 필터를 선택했을 때 목록을 재설정하면 행복 할 것입니다. 나는 Ajax와 잘 맞지 않으므로 Ajax를 사용하여 필터를 적용하고 이러한 필터를 무한 스크롤에 전달하는 방법에 대한 조언을 찾고 있었다. – LeeTee

+0

위의 편집 된 답변을 참조하여 서버 측 필터를 적용하는 방법을 확인하십시오. –

+0

고마워요.하지만 선택한 필터를 무한 스크롤로 통과 시키려면 어떻게해야합니까? – LeeTee

0

이렇게하면 필터를 적용 할 때 전체 결과가 변경되므로 데이터를 다시로드하고 스크롤을 재설정해야합니다. 그래서 필터링과 무한 스크롤을 함께 사용해서는 안됩니다.

나는 이전 프로젝트에서 같은 일을했다. 희망이 당신을 위해 작동합니다.

+0

예, 스크롤을 다시 설정해 드리겠습니다. 나는 그것을 기대할 것이라고 생각한다. 이전 프로젝트에서 어떻게 했습니까? Ajax 필터링을 사용하여 스크롤을 재설정하는 방법에 대해 조언 할 수 있습니까? – LeeTee

+0

[Facescroll] (http://www.dynamicdrive.com/dynamicindex11/facescroll/index.htm)을 사용했습니다. 기본적으로 무한 스크롤을 지원하지 않지만 스크롤 막대를 내용에 동적으로 추가하여 무한 스크롤을 처리하도록 라이브러리를 사용자 정의합니다.
Google의 필터링은 즉석 검색입니다. 사용자가 문자를 입력하면 setTimeout은 ajax 함수를 호출합니다. '$ ('#의 searchInput ')를 keyDown (함수 (이벤트) { \t 경우 (windowDrawing.searchTimer) { \t \t 사항 clearTimeout (windowDrawing.searchTimer). \t} \t windowDrawing.searchTimer =에서는 setTimeout (함수() { \t \t myWindowProcess.ajaxGetWindows(); \t}, }); –

관련 문제