2012-12-10 27 views
17

我是AnuglarJS的新手,並且已經使用它創建了一個小型網絡應用程序,我想使用Facebook JavaScript SDK,但是使用最佳實踐(依賴注入到控制器,維護應用程序結構和可測試性)。如何正確注入Facebook JavaScript SDK到AngularJS控制器?

我發現這https://groups.google.com/forum/#!msg/angular/bAVx58yJyLE/Kz56Rw-cQREJ 但它非常混淆新人到這個框架(模塊,服務和工廠沒有很好地解釋恕我直言)。

那麼,在AngularJS應用中使用Facebook SDK的正確方法是什麼?

回答

5

其實我也不得不這樣做......我沒有跟我的代碼,它可能是專有的,無論如何......但它基本上是這樣的:

// create a simple factory:  
app.factory('facebook', ['$window', function($window) { 

    //get FB from the global (window) variable. 
    var FB = $window.FB; 

    // gripe if it's not there. 
    if(!FB) throw new Error('Facebook not loaded'); 

    //make sure FB is initialized. 
    FB.init({ 
     appId : 'YOUR_APP_ID' 
    }); 

    return { 
     // a me function 
     me: function(callback) { 
      FB.api('/me', callback); 
     } 

     //TODO: Add any other functions you need here, login() for example. 
    } 
}]); 

// then you can use it like so: 
app.controller('SomeCtrl', function($scope, facebook) { 

    //something to call on a click. 
    $scope.testMe = function() { 

     //call our service function. 
     facebook.me(function(data) { 
      $scope.facebookUser = data; 

      //probably need to $apply() this when it returns. 
      // since it's async. 
      $scope.$apply(); 
     }); 
    }; 
}); 

如果有任何這些錯誤讓我知道,我會查找我的工作代碼,看看我錯過了什麼。但這應該是關於它的。

+0

$ watch(這可能是最好的方式來提高性能)我應該在HTML中像Facebook一樣初始化SDK異步,或者init在工廠完成,並且html只包含sdk? –

+0

該代碼似乎工作,但數據綁定不起作用的異步調用,我嘗試使用$ q和$ scope。$應用在控制器,並得到它的部分工作。但我讀到,控制器是放置這些的不好的地方。那麼如何更改工廠以使用這些異步API調用? –

+3

只是爲了擴大@blesh的答案。 查看這個更開發的例子: http://jsfiddle.net/bradbirdsall/ggmRQ/6/ – elviejo79

0

工作的唯一方法是將舊版本的sdk包含在索引頁中。

因爲我從@elviejo實現了@blesh或擴展版本的相同解決方案,如果我們有一個調用控制器時調用的函數,它們都有問題,所以FB未初始化的機會非常大高,這將使呼叫失敗,同時調用undefined :)

希望這將有助於避免頭痛與此。

2

我寫過這個angularjs-facebook服務。 首先你在你的應用模塊配置方法上初始化它,以初始化你的Facebook應用程序ID和其他設置。

那麼你只是喜歡從控制器調用Facebook服務和調用Facebook方法異步就像平常一樣。

https://github.com/ciul/angularjs-facebook

5

2015年編輯!

這是一個古老的答案。我會建議你看看在github上流行的角模塊怎麼做,或乾脆使用它們:

老回答

由於應用程序啓動時的調用問題,我使用以下方法,該方法加載該SDK已經被加載後,方可應用:

window.fbAsyncInit = function() { 
FB.init({ 
    appId: window.fbConfig.appID, 
    channelUrl: '//' + window.location.hostname + window.location.pathname + 'channel.php', 
    status: window.fbConfig.oInitOptions.bStatus || true, 
    cookie: window.fbConfig.oInitOptions.bCookie || true, 
    xfbml: window.fbConfig.oInitOptions.bXfbml || true 
}); 


// Get Login Status once at init 
window.FB.getLoginStatus(function (oResponse) { 
    if (oResponse && oResponse.status) { 
     window.fbConfig.sAuthStatus = oResponse.status; 
    } 

    // Bootstrap app here only after the sdk has been loaded 
    angular.bootstrap(document.body, ['fbAngularApp']); 
}); 
}; 

// Load the SDK Asynchronously 
(function (d) { 
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; 
if (d.getElementById(id)) { 
    return; 
} 
js = d.createElement('script'); 
js.id = id; 
js.async = true; 
js.src = '//connect.facebook.net/' + window.fbConfig.lng + '/all.js'; 
ref.parentNode.insertBefore(js, ref); 
}(document)); 
0

我難倒這一段時間,我用$腕錶解決它

//setup watch for FB API to be ready 
//note that since you use $window, you need to inject it into your controller 
//angular.module('myApp').controller('appController', function ($scope, $window, ...) { 
$scope.FBListener = $scope.$watch(function() { 
    return $window.FB; 
}, function (newVal, oldVal) { 
    // FB API loaded, make calls 
    console.log("FB is ready"); 
    //functions that do FB API calls 
    $scope.getFBEvents(); 
    $scope.getFBPosts(); 
}); 

當FB已經加載,可以清除通過調用$scope.FBListener();