2013-08-16 33 views
0

我使用Facebooks Javascript API,在我的jquery移動網站,爲了從facebook公共頁面下載相冊和照片,並將它們呈現給我的網站。多個異步調用(javascript臉譜api)失敗

這個API在事情的完成方面非常簡單,我使得所有的工作都相當簡單。

是我迄今所做的和當用戶點擊一個按鈕,我打開一個頁面,其中的JavaScript FB API調用並動態地生成特定的Facebook的所有專輯的列表工作

頁面,所有照片等,這很好。當調用API時,它只提取25張專輯,當我有更多專輯可以讀取時,我有一個「更多專輯」按鈕,用戶點擊它可以再次調用API並獲取更多專輯。這偉大工程太...

的問題

我的問題出現了,當我決定,我想有2個不同的Facebook頁面,我想從導入相冊/照片。所以我做了一個有2個選項的水平按鈕(臉書頁面1,臉書頁面2),使navBar持久,當我點擊其中一個按鈕時,我需要一個API調用,並獲取每個頁面的相冊。這可悲的是不工作...當我打電話給2頁中的一個,一切正常。即使是「更多專輯」按鈕的作品。但是當我導航到另一個Facebook頁面時,對api的調用不起作用......我無法理解爲什麼......「更多專輯」按鈕的作品,這意味着我可以對api進行多次調用。但是爲什麼當我使用ajax導航到我的jquery移動站點上的其他頁面時,該呼叫不能完成?我在JavaScript文件中添加了一個警報,我看到它,這意味着代碼被調用。但是當我把警報放在實際的api調用中時,我無法看到任何提醒....我想這意味着由於某種原因,呼叫被阻止...

任何想法可能發生在這裏?

我對2張的專輯之一的JavaScript看起來像這樣:

$('#photosNJ').on("pageshow", function() { 
     var albumPhotos = new Array(); 
     var albumThumbnails = new Array(); 
     var x=0; 
     var next; 
     var times=0; 
     var dataLength=0; 

     // start the entire process 
     window.fbAsyncInit = function() { 
      // init the FB JS SDK 
      FB.init({ 
       appId  : '564984346887426',             // App ID from the app dashboard 
       channelUrl : 'channel.html',              // Channel file for x-domain comms 
       status  : true,                // Check Facebook Login status 
       xfbml  : true                // Look for social plugins on the page 
      }); 
      $.mobile.loading("show"); 
      FB.api('169070991963/albums', checkForErrorFirst(getAlbums)); 
      //$.mobile.loading("hide"); 

     } 


     // checkForErrorFirst wraps your function around the error checking code first 
     // if there is no response, then your code will not be called 
     // this allows you to just write the juicy working code 
     // and not worry about error checking 
     function checkForErrorFirst(myFunc) { 
      return function(response) { 
       if (!response || response.error) { 
        alert("Error !"); 
       } else { 
        myFunc(response); 
       } 
      }; 
     } 

     function getAlbums(response) { 
      //if statement checks , if there are any more albums to load. If not we disable the "More Albums" button. 
      if(response.paging.next == undefined) $("#loadMoreAlbums").parent().hide(); 
      //variable next holds the URL for the next 25(or less) albums 
      next = response.paging.cursors.after; 
      dataLength = response.data.length + dataLength; 
      for (var i=0; i < response.data.length; ++i) { 
       processAlbum(response.data[i], i+x); 
      } 
      x = x+i; 
      console.log(x); 
     } 


     function processAlbum(album, i) { 
      FB.api(album.id + "/photos?limit=300", checkForErrorFirst(populateAlbum(album, i))); 
     } 


     function populateAlbum(album, i) { 
      return function(response) { 
       for (var k=0; k < response.data.length; ++k){ 
        albumThumbnails[i] = albumThumbnails[i]||[]; 
        albumThumbnails[i][k] = response.data[k].picture; 
        albumPhotos[i] = albumPhotos[i]||[]; 
        albumPhotos[i][k] = response.data[k].source; 
       } 
       // now that we've populated the album thumbnails and photos, we can render the album 
       FB.api(album.cover_photo, checkForErrorFirst(renderAlbum(album, i))); 
      }; 
     } 

     function renderAlbum(album, i) { 
      times++; 
      if(times == dataLength) $.mobile.loading("hide"); 
      return function(response) { 
       var albumName = album.name; 
       var albumCover = album.cover_photo; 
       var albumId = album.id; 
       var numberOfPhotos = album.count; 

       // render photos 
       $(".albums").append('<li>'+ 
       '<a href="#Gallery' + i + '"' + 'data-transition="slidedown">'+ 
       '<img src= "' + response.picture + '" />'+ 
       '<h2>' + albumName + '</h2>'+ 
       '<p>' + "Number of Photos: " + numberOfPhotos +'</p>'+ 
       '</a>'+ 
       '</li>').listview('refresh'); 

       $("#photosNJ").after('<div data-role="page" data-add-back-btn="true" id=Gallery'+ i + 
       ' class="gallery-page"' + ' data-url="Gallery' + i + '"> ' + 
       ' <div data-role="header"><h1>Gallery</h1></div> ' + ' <div data-role="content"> ' + 
       ' <ul class="gallery"></ul> ' + ' </div> ' + 
       ' </div> '); 

       for(var n=0; n < albumPhotos[i].length; n++) { 
        $('#Gallery' + i + ' .gallery').append('<li><a href="' + albumPhotos[i][n] 
        + '" rel="external"><img src="' + albumThumbnails[i][n] + '"' + '/> </a> </li>'); 
       } 

       //adding a "More Photos" button inside every album 
       // $('#Gallery' + i + ' .gallery').after('<button type="button" class="loadMorePhotos">More Photos...</button>'); 
      }; 



     } 

     // Load the SDK asynchronously 
     (function(d, s, id){ 
      var js, fjs = d.getElementsByTagName(s)[0]; 
      if (d.getElementById(id)) {return;} 
      js = d.createElement(s); js.id = id; 
      js.src = "//connect.facebook.net/en_US/all.js"; 
      fjs.parentNode.insertBefore(js, fjs); 
     }(document, 'script', 'facebook-jssdk')); 

     //"More Albums" button 
     $("#loadMoreAlbums").click(function(){ 
      // start the entire process 
      window.fbAsyncInit = function() { 
      // init the FB JS SDK 
      FB.init({ 
       appId  : '564984346887426',         // App ID from the app dashboard 
       channelUrl : 'channel.html',          // Channel file for x-domain comms 
       status  : true,            // Check Facebook Login status 
       xfbml  : true            // Look for social plugins on the page 
      }); 
      } 
      //when the "More Albums" button is pressed , we make a call at the API for the next 25(or less) albums , using the "next" URL 
      $.mobile.loading("show"); 
      FB.api('169070991963/albums?after=' + next +"'", checkForErrorFirst(getAlbums)); 
     }); 
}); 

你可以看到調用API,動態生成HTML頁面的顯示專輯在ListView,人口包含照片的相冊,更多相冊按鈕等......我的其他Facebook頁面的JavaScript是IDENTICAL,只有頁面ID發生變化。在這一點上,我想指出,如果我先加載其他頁面,然後再次加載第二個調用是不工作的。這意味着我沒有專輯中的某個特定問題,而不是第二個調用永遠不會運行的問題。

下面是HTML頁面,以防萬一你需要看看我究竟想要做:

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <title>jQuery Mobile Web App</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <!--<link href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" rel="stylesheet" type="text/css"/>--> 
    <link rel="stylesheet" href="themes/EspacioJoven.min.css" /> 
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile.structure-1.3.1.min.css" /> 
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
    <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script> 
    <link rel="stylesheet" href="themes/custom.css" /> 

    <!--Used by PhotoSwipe Plugin --> 
    <script type="text/javascript" src="photoSwipe/klass.min.js"></script> 
    <script type="text/javascript" src="photoSwipe/code.photoswipe.jquery-3.0.5.min.js"></script> 
    <script type='text/javascript' src='photoSwipe/photoSwipeCall.js'></script>  
    <link href="photoSwipe/jquery-mobile.css" type="text/css" rel="stylesheet" /> 
    <link href="photoSwipe/photoswipe.css" type="text/css" rel="stylesheet" /> 
    <!--Used by PhotoSwipe Plugin --> 

    <script type='text/javascript' src='javascript/createFb2.js'></script> 
    <script type='text/javascript' src='javascript/createFb.js'></script> 

</head> 
<body> 
<div data-role="page" id="home" data-theme = "a" > 
    <div data-role="content"> 
     <h2 id="banner">Joven Mobile</h2> 
     <div class="main_menu"> 
      <ul data-inset="true" data-role="listview"> 
       <li><a href="#espaJoven"><img src="themes/icons/news.png" alt="Information" class="ui-li-icon">Es Joven</a></li> 
       <li><a href="#noJoven"><img src="themes/icons/research.png" alt="Information" class="ui-li-icon">La Noche es Joven</a></li> 
       <li><a href="#photosNJ"><img src="themes/icons/staff.png" alt="Information" class="ui-li-icon">Multimedia</a></li> 
       <li><a href="#sanrJoven"><img src="themes/icons/students.png" alt="Information" class="ui-li-icon">Sar Joven</a></li> 
      </ul>  
     </div> <!-- /main_menu --> 
    </div> <!-- /content --> 
</div> <!-- /page --> 

<div data-role="page" id="photosNJ" data-theme="a" data-add-back-btn="true" data-back-btn-text="Back"> 
    <!--<script type='text/javascript' src='javascript/createFbAlbums.js'></script> --> 
    <div data-role="header" data-id="fixedNav" data-position="fixed"> 
     <h1>Application Title</h1> 
     <a href="#" data-icon="back" data-rel="back" title="Go back">Back</a> 
     <div data-role="navbar"> 
      <ul> 
       <li><a href="#photosNJ" class="ui-btn-active ui-state-persist">Photos Noche Joven</a></li> 
       <li><a href="#photosEJ">Photos Esp Joen</a></li> 
       <li><a href="#videos">Videos</a></li> 
      </ul> 
     </div> <!-- /navbar --> 
    </div> <!-- /header --> 
    <div data-role="content"> 
     <ul data-role="listview" data-inset="true" class="albums"> 
      <!-- Here the albums are created through javascript (createAlbums.js) --> 
     </ul> 

     <button type="button" id="loadMoreAlbums">More Albums...</button> 

    </div> <!-- /content --> 
    <!-- <div id="fb-root"></div> --> 

</div> 


<div data-role="page" id="photosEJ" data-theme="a" data-add-back-btn="true" data-back-btn-text="Back"> 
    <!--<script type='text/javascript' src='javascript/createFbAlbums2.js'></script>--> 
    <div data-role="header" data-id="fixedNav" data-position="fixed"> 
     <h1>Application Title</h1> 
     <a href="#" data-icon="back" data-rel="back" title="Go back">Back</a> 
     <div data-role="navbar"> 
      <ul> 
       <li><a href="#photosNJ">Photos Noche Joven</a></li> 
       <li><a href="#photosEJ" class="ui-btn-active ui-state-persist">Photos Espacio Joven</a></li> 
       <li><a href="#videos">Videos</a></li> 
      </ul> 
     </div> <!-- /navbar --> 
    </div> <!-- /header --> 
    <div data-role="content"> 
     <ul data-role="listview" data-inset="true" class="albums2"> 
      <!-- Here the albums are created through javascript (createAlbums.js) --> 
     </ul>  

     <button type="button" id="loadMoreAlbums2">More Albums...</button>  
    </div> <!-- /content --> 
    <!-- <div id="fb-root"></div> --> 
</div> 

</body> 
</html> 

非常感謝你,如果你決定讀,直到這一步非常多。 ANY,絕對任何在這一個意見或想法是我超價值,所以請如果您有任何我想分享:)

提琴手:http://jsfiddle.net/lessisv/GW4PK/

轉到多媒體有我有2個標籤「照片Noche Joven」,「照片Espacio Joven」。你可以看到第一個正常加載。另外,如果你下來,你可以看到「更多專輯」按鈕,這也可以正常工作,並調用API。問題是,當我去「照片Espacio Joven」,由於我描述的原因,通話不起作用。

+0

你可以創建一個小提琴嗎?這是相當多的代碼。 – DrColossos

+0

提琴手補充了先生。非常感謝:) –

+0

它看起來像_#photosNJ_與_#photosEJ_衝突。如果您刪除_#photosNJ_,_#photosEJ_作品的代碼。我建議你將兩個代碼合併爲一個。問題在於再次執行代碼時,當您移至其他頁面時,「window.fbAsyncInit」未運行。 – Omar

回答

2

首先,您的loadMoreAlbums處理程序中不需要window.fbAsyncInit。你先定義相同的函數 - 這就夠了。

其次,您不要多次使用FB.init - 只能使用一次。因爲它在window.fbAsyncInit內定義,並且該函數在加載SDK時由Facebook SDK調用。並且檢查腳本是否已經加載:

if (d.getElementById(id)) {return;} 

這意味着您加載一次FB腳本並初始化FB一次。

最主要的是,您不能在一個作用域(「pageshow事件」處理程序之一)中初始化FB對象(FB.init),然後在另一個作用域(另一個處理程序)中使用FB.api。這就是爲什麼你會得到空的結果。

您可以嘗試幾種解決方案。

1.您可以在每次頁面更改時初始化FB。

只檢查FB對象是否存在並調用window.fbAsyncInit()。您可以通過改變

if (d.getElementById(id)) {return;} 

趕快試試這個解決方案

if (d.getElementById(id)) {window.fbAsyncInit(); return;} 

這是醜陋的方式。

2.你真的應該重構你的代碼。

Init FB在頂層 - 不在兩個處理程序中;創建一個處理程序 - 並在頁面更改時調用它。您可以傳遞必要的參數或使用DOM元素數據。

PS。每當頁面更改時,都會添加一個新的loadMoreAlbums處理函數。您切換到另一個相冊,返回並獲得兩個電話和兩個數據,再次切換並獲得三重數據。

$(document).on("pageshow", '#photosNJ', function() { 
    ... 

    $("#loadMoreAlbums").click(function() { 
     ... 
    }); 
    ... 
}); 
1

那麼,有很多話要說...

  1. 你必須因素事情,以避免爲每個「頁」
  2. 創建功能,您不必調用不止一次FB.init多,因爲fbAsyncInit將只調用一次,和FB.api查詢檢索專輯將不會被解僱下一次你打電話FB.init(這就是爲什麼你不能加載第二頁的數據)
  3. 是更多的按鈕工作,即使你有一個FB.init,因爲你的FB.api請求不在fbAsyncInit函數內
  4. 作爲你的頁面都是公開的,你不需要或不知道用戶是否連接,如果他接受了你的應用程序,這樣你就可以只FB.init後火FB.api,但在其他情況下,你將不得不實施FB.login功能或至少一個偵聽狀態更改事件要知道,如果你的用戶連接,再火的請求
  5. ...

如果你想多看一眼的方式來實現這一切,看看這裏:http://jsfiddle.net/ZES3X/