web-dev-qa-db-ja.com

Facebook JavaScript APIのページングは​​どのように機能しますか?

Facebookニュースフィードの先週の投稿をJavaScript SDKで回復しようとしています。最初のページを取得することはできますが、他のページを繰り返し処理する方法がわかりません。私は次のコードでそれを試しました:

 $('#loadPosts').bind('click', function() {     
            FB.api('/me/home',{since:'last week'}, getPosts);   
          });

 getPosts = function(response){
        for (element in response.data){
            post = response.data[element]
            console.log(post);          
          }

          previousPage = response.paging.previous;        
          console.log(previousPage);

          // can i call FB.api(previousPage, getPosts); ??      

      }

しかし、前のページと同じようにURLを取得しており、そのURLからJavaScript FB.apiを呼び出す方法がわかりません。何か案は?

24
Fgblanch

さて、私の古い答えが明らかにしていると私がまだ信じている単純な問題については多くの愚痴があるようです。とにかく、ベビーシッターをさせてください。 :)

最初:最初のページから「前の」ページに実際に移動できないことがわかりました。理想的には、そうすべきです。だから、あなたがフォローしたいと思うかもしれないと私が提出したバグはここにあります: https://developers.facebook.com/bugs/391562790938294?browse=search_50fcac3ce094e7068176315

2番目:これが設計によるものである場合、最初のページから「前へ」に戻ることはできません(があるため前へ)、しかしあなたはきっと「次へ」に行くことができます。ただし、APIはカーソルとして動作し、先に進んだため、「前の」ページが機能します。

質問への回答:
前のページと同じようにURLを取得していますが、そのURLからJavaScript FB.apiを呼び出す方法がわかりません。何か案は?

はい、FB.apiを呼び出すことができます。しかし、代わりにHTTP GET呼び出しを行うことをお勧めします。また、previousは{"data":[]}のような空の配列を返す場合があることに注意してください。

前/次のページを取得する方法?
ここでは、jQueryを使用する小さなコードを書いています。コードを読みたくない場合は、2つの方法があります。

  1. 前/次のURLを使用して、HTTP GETリクエストを作成します。これは、空でない場合、「前の」「次の」リンクの次のセットで提供されます。
  2. URLを解析し、JSONがFB.apiに渡すときにクエリ文字列を取得します。解析には jQuery BBQ pluging を使用しました。

重要な注意:この例では、「次の」URLを使用しています。これは、最初のリクエストで「前の」を使用すると、過去からの投稿。ただし、数ページ先に進んだら、「前の」URLを使用できます。 Googleの結果と同様に、1ページに戻ることはできませんが、> 1のページからは移動できます(以下の例3を参照)。これはページネーションと呼ばれます。

例1:HTTP GETを使用したコード(推奨):(3つの投稿/ページを読み込み、3つの次のページを表示します)

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="https://raw.github.com/cowboy/jquery-bbq/master/jquery.ba-bbq.min.js"></script>
<script>

var i =0;
var getPosts = function (response){
          for (element in response.data){
            post = response.data[element]
            console.log(post.id + ": " +post.message);          
          }



          // can i call FB.api(nextPage, getPosts); ??
          if(i < 2){
              nextPage = response.paging.next;        
              console.log(nextPage);
              i++;
              //Method 1: I use it.
              $.get(nextPage, getPosts, "json"); //optional: $.getJSON can be use instead
          }

      }

$(document).ready(function(){

$('#loadPosts').bind('click', function() {
            FB.api('/me/home',{since:'yesterday','limit': '3'}, getPosts);   
          });
})
</script>
</head>
<body>
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    // init the FB JS SDK
    FB.init({
      appId      : 'XXXXXXXXXXXX', // FILL YOUR APP ID HERE!
      status     : true, // check the login status upon init?
      cookie     : true, // set sessions cookies to allow your server to access the session?
    });

    // Additional initialization code such as adding Event Listeners goes here

  };
</script>
<button id="loadPosts">Load Posts</button>
<p>Please open developer console to see what's happening. In Firefox, you can use ctrl+shift+k, and in Chrome/Chromium use ctrl+shift+i</p>
</body>
</html>

応答

100004192352945_156620584487686: undefined
137723270230_10152423499430231: On this day, please spare a thought for those fellow citizens, for whom I just spare a thought and do nothing else.
642965867_10151211036740868: Thanks everyone for their wishes! The wishes made my day!

https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD&until=1359184568
367116489976035_536776529676696: Rage. Quit. Life.
899605553_10152450871820554: undefined
367116489976035_417820828298092: undefined

https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD&until=1359179890
137723270230_10152423148745231: Pratibha Patil used to love the Republic Day Parade, especially the part where the visiting Chief Guest extended her an invitation to visit his/her own country.
137723270230_10152423131700231: The Kingfisher tableau at Republic Day Parade was so simple. Vijay Mallya riding a bicycle.
367116489976035_484460034950769: undefined

例2:FB.apiを使用したコード:(3つの投稿/ページを読み込み、3つの次のページを表示します)

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="https://raw.github.com/cowboy/jquery-bbq/master/jquery.ba-bbq.min.js"></script>
<script>

var i =0;
var getPosts = function (response){
          for (element in response.data){
            post = response.data[element]
            console.log(post.id + ": " +post.message);          
          }



          // can i call FB.api(nextPage, getPosts); ??
          if(i < 2){
              nextPage = response.paging.next;        
              console.log(nextPage);
              i++;

              //Method 2: If you have to call FB.api
              var params = jQuery.deparam.querystring(nextPage);
              console.log(JSON.stringify(params, null, 2));
              FB.api('/me/home', params, getPosts)
          }

      }

$(document).ready(function(){

$('#loadPosts').bind('click', function() {
            FB.api('/me/home',{since:'yesterday','limit': '3'}, getPosts);   
          });
})
</script>
</head>
<body>
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    // init the FB JS SDK
    FB.init({
      appId      : 'XXXXXXXXXXXX', // FILL YOUR APP ID HERE!
      status     : true, // check the login status upon init?
      cookie     : true, // set sessions cookies to allow your server to access the session?
    });

    // Additional initialization code such as adding Event Listeners goes here

  };
</script>
<button id="loadPosts">Load Posts</button>
<p>Please open developer console to see what's happening. In Firefox, you can use ctrl+shift+k, and in Chrome/Chromium use ctrl+shift+i</p>
</body>
</html>

応答

367116489976035_536776529676696: Rage. Quit. Life.
899605553_10152450871820554: undefined
367116489976035_417820828298092: undefined
{
  "limit": "3",
  "access_token": "AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD",
  "until": "1359179890"
}

137723270230_10152423148745231: Pratibha Patil used to love the Republic Day Parade, especially the part where the visiting Chief Guest extended her an invitation to visit his/her own country.
137723270230_10152423131700231: The Kingfisher tableau at Republic Day Parade was so simple. Vijay Mallya riding a bicycle.
367116489976035_484460034950769: undefined

https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD&until=1359178140
{
  "limit": "3",
  "access_token": "AAACYjXGS5FQBAIR3brc2LibjBcZCi2kRJUybG8VMaaJSZARQ8SzNE7BE4PBrDIFVZB0AaVEa1dZCpX1fhCvoD2rnq8uc8OGaIFhO9uvVXAZDZD",
  "until": "1359178140"
}
655515199_403590309726450: a good resolution to take on Republic Day
505588854_496901583686790: Love the secret world that slow motion reveals.
693811975_10151217837201976: undefined

例3:実行中:page1-> page2-> page1またはpage-> next-> previous次のコードはpage1をロードしてから、「next "ページ(page2)、次に" previous "を使用してpage1に戻ります

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" src="https://raw.github.com/cowboy/jquery-bbq/master/jquery.ba-bbq.min.js"></script>
<script>

var i =0;
var getPosts = function (response){
          for (element in response.data){
            post = response.data[element]
            console.log(post.id + ": " +post.message);          
          }



          // can i call FB.api(nextPage, getPosts); ??
          if(i < 2){
              nextPage = response.paging.next;        
              if(i==1)
                nextPage = response.paging.previous;

              console.log(nextPage);
              i++;
              $.get(nextPage, getPosts, "json"); //optional: $.getJSON can be use instead
          }

      }

$(document).ready(function(){

$('#loadPosts').bind('click', function() {
            FB.api('/me/home',{since:'yesterday','limit': '3'}, getPosts);   
          });
})
</script>
</head>
<body>
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    // init the FB JS SDK
    FB.init({
      appId      : 'XXXXXXXXXXXX', // FILL YOUR APP ID HERE!
      status     : true, // check the login status upon init?
      cookie     : true, // set sessions cookies to allow your server to access the session?
    });

    // Additional initialization code such as adding Event Listeners goes here

  };
</script>
<button id="loadPosts">Load Posts</button>
<p>Please open developer console to see what's happening. In Firefox, you can use ctrl+shift+k, and in Chrome/Chromium use ctrl+shift+i</p>
</body>
</html>

応答

PAGE1:
367116489976035_536806916340324: How big is the Solar System?
Full infographic here: http://bit.ly/WmzfVn
137723270230_10152423534790231: "Sociologist" Ashis Nandy has claimed that most of the corrupt came from OBC/SC/ST castes.
Following this, Corrupt people have strongly condemned Nandy's attempts to divide them on caste lines. They'll be united in loot, forever.
100004192352945_156620584487686: undefined

PAGE2:
https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAKqIMyCVYjH9upK4e2bjUwLoVbbFDL0ffc0SZBTVR9MUFGV4ZCq6HBdFIadFMpLDC3ATMZCJ4GPsXWpG4qTGODavuvzLAZDZD&until=1359185659

137723270230_10152423499430231: On this day, please spare a thought for those fellow citizens, for whom I just spare a thought and do nothing else.
642965867_10151211036740868: Thanks everyone for their wishes! The wishes made my day!
367116489976035_536776529676696: Rage. Quit. Life.

PAGE1:
https://graph.facebook.com/677811901/home?limit=3&access_token=AAACYjXGS5FQBAKqIMyCVYjH9upK4e2bjUwLoVbbFDL0ffc0SZBTVR9MUFGV4ZCq6HBdFIadFMpLDC3ATMZCJ4GPsXWpG4qTGODavuvzLAZDZD&since=1359185123&__previous=1

367116489976035_536806916340324: How big is the Solar System?
Full infographic here: http://bit.ly/WmzfVn
137723270230_10152423534790231: "Sociologist" Ashis Nandy has claimed that most of the corrupt came from OBC/SC/ST castes.
Following this, Corrupt people have strongly condemned Nandy's attempts to divide them on caste lines. They'll be united in loot, forever.
100004192352945_156620584487686: undefined

古い回答

limitoffsetsinceおよびuntilパラメータを使用して目標を達成します。

参照: http://developers.facebook.com/docs/reference/api/

ページング

接続を照会する場合、接続データのフィルタリングとページングを可能にするいくつかの便利なパラメーターがあります。

以下は、last weekメッセージから21st - 30thからyesterdayまでのすべての投稿を取得する必要があります(基本的に、ページごとに10メッセージの3ページ目)。

 FB.api(
  '/me/home',
  {
    'since':'last week',
    'limit': '10',
    'offset': '20',
    'until': 'yesterday'
  }, 
  getPosts
); 

私はテストしたところ、うまくいきました。私はlimit = 4を使用しました。これはページサイズのようなものです。したがって、2011年2月2日(UNIXタイムスタンプ:1296626400)から今日までデータをフェッチすると、これを使用して

https://graph.facebook.com/me/home?access_token=[AUTH_TOKEN]&since=1296626400&limit=4

データを返します。また、次のページに移動するためのURLも返します

{
   "data": [
      <ARRAY OF POSTS HERE>
   ],
   "paging": {
      "previous": "https://graph.facebook.com/me/home?access_token=[NEW_AUTH_TOKEN]&since=1298026753&limit=4",
      "next": "https://graph.facebook.com/me/home?access_token=[NEW_AUTH_TOKEN]&limit=4&until=1298023222"
   }
}

JSONオブジェクトのpreviousおよびnext属性を安全に使用して、次のページ(または前のページ)にジャンプできます。これが最も簡単な方法のようです。

ところで、これを機能させるには、\u00257C|に変換する必要がありました。

32
Nishant

(paging.nextオブジェクトを使用して)次のページを取得したいだけの場合は、jQuery.getJSONリクエストを実行できます。次のようなもの:

function loadAlbums(){
    FB.api('/me/albums', function(response){
        handleAlbumsResponse(response);
    });
}

function handleAlbumsResponse(response){
    var albums = response.data;

    for( var i in albums){
        var album = albums[i];
        $('#albums ul').append('<li><a href="#">' + album.name + '</a></li>');
    }

    if( response.paging.next){
        console.log('fetching next page...');
        $.getJSON(response.paging.next, function(response){                
            handleAlbumsResponse(response);
        });
    } 
} 
7
Craig Myles

質問の重要な制約は、応答で提供された「次の」URLを使用できないことです。

最初に、より一般的な質問をして、質問に回答してみます。

Facebookアプリのユーザーエクスペリエンスを作成するにはどうすればよいですか?さらに多くのアイテムを呼び出すたびに同じ量のアイテムが返されます。

ユーザーが「追加」をリクエストして10個のアイテムを取得し、「追加」を押して4個、次に7個を取得した場合、彼女は私たちのアプリにバグがあると思うかもしれません。

Open Graph intro page では、ページング用のさまざまなパラメーターが導入されています。これらは:

限界

オフセット

until

以来

「ページング」の見出しの下で述べたように。ただし、offsetをインクリメントする制限とオフセットを使用してソリューションを実装すると、次のようになります。

https://graph.facebook.com/me/home?limit=10&offset=OFFSET

oFFSETが各リクエストの制限によって増加する場合、返される結果の数は、指定した「制限」パラメーターと等しくないことがあります。これは、パラメーターがFacebook側beforeに適用され、照会された結果がビューアーに表示されるかどうかを確認するためです。私たちは10を要求しますが、8アイテムを受け取るかもしれません。

これは、アプリの「more」リクエストで常に同じ量のアイテムが返されるようにする場合は、制限とオフセットを増分するソリューションを使用できないことを意味します。

これで提案された解決策 ブログ (Facebookプラットフォームチームで作業する)Jeff Bowenがこのロジックです:

  • 制限= YOUR_LIMITのアイテムをリクエストします。
  • レスポンスの最後のアイテムのcreated_timeフィールドを取得します。
  • since = RETRIEVED_CREATED_TIMEおよびlimit = YOUR_LIMITで次の10アイテムをリクエストする

上記のブログ投稿の例に基づくコードサンプルは次のとおりです。

var graphURL = "https://graph.facebook.com/me/home?" +
                 "callback=processResult&" +
                 "date_format=U&" +
                 "limit=10";

function loadPosts() {
  var script = document.createElement("script");
  script.src = graphURL;
  document.body.appendChild(script);
}

function processResult(posts) {
  if (posts.data.length == 0) {
    document.getElementById("loadMore").innerHTML =
      "No more results";
  }
  else {
    graphURL = graphURL + "&until=" +
      posts.data[posts.data.length-1].created_time;

    for (var post in posts.data) {
      var message = document.createElement("div");
      message.innerHTML = posts.data[post].message;
      document.getElementById("content").appendChild(message);
    }
  }
}

このソリューションは、JSON応答でURLを使用せずに、ユーザーのニュースフィードから次の10項目を時系列で取得します。

3
Gunnar Karlsson

それは働いています

    function friends_list()
    {

        for (var x = 0; x<500; x++)
        {
            FB.api(
            '/me/friendlists/',
            'GET',
            {"fields":"id","offset":x},
            function(response) {
            for (i = 0; i < response.data.length; i++) 
            { 

            document.getElementById("friends_list").innerHTML =  
            document.getElementById("friends_list").innerHTML + "<br>" + response.data[i].id; 

            }
            document.getElementById("friends_list").innerHTML =  
            document.getElementById("friends_list").innerHTML + "<br>" ;
            }
            );
        }


    }
0
Googlian

質問がとても古いことに気づきました。私の答えは最近のFB jsSDK(2017)に当てはまります:)

実際、これは前任者が説明したものよりも簡単で、いくぶん直感的です。 FB jsSDKそれ自体はAPIであり、それ自体で応答のページをナビゲートでき、同じ手段を使用できると期待されていますか?

function getPosts(){
    FB.api('/me/posts', 'GET', {limit:250}, cbGetPosts);
}

function cbGetPosts(response){
    // do your stuff with response.data
    if(response && response.paging){
     FB.api(response.paging.next, cbGetPosts); // yep, is this simple
    }
}

明らかに、次のキーが定義されている限り、これは次のページを要求しますが、コンセプトを証明しています。

0
bluehipy