2012-12-10 12 views
17

Sono nuovo di AnuglarJS e con esso ho già creato una piccola web-app, Vorrei usare l'SDK JavaScript di Facebook con esso, ma usando le migliori pratiche (l'iniezione di dipendenza ai controller, per mantenere la struttura e la testabilità dell'app).come iniettare correttamente Facebook JavaScript SDK ai controller AngularJS?

Ho trovato questo https://groups.google.com/forum/#!msg/angular/bAVx58yJyLE/Kz56Rw-cQREJ ma è molto confuso per qualcuno nuovo a questo quadro (moduli, servizi e fabbriche non sono spiegate bene IMHO).

quindi, qual è il modo corretto di utilizzare l'SDK di Facebook all'interno di un'app AngularJS?

risposta

5

mi hanno effettivamente dovuto fare questo ... non ho il codice con me, ed è probabilmente proprietaria comunque ... ma era essenzialmente come questo:

// 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(); 
     }); 
    }; 
}); 

Se ci sono errori in questo fammi sapere, e cercherò il codice di lavoro che ho e vedere cosa ho perso. Ma dovrebbe essere al riguardo.

+0

dovrei inizializzare l'SDK asincrona nell'html come suggerito da Facebook o l'init è fatto in fabbrica e l'html include solo il sdk? –

+0

il codice sembra funzionare, ma i binding di dati non funzionano con le chiamate asincrone, ho provato ad usare $ q e $ scope. $ Applicare nel controller e farlo funzionare parzialmente. ma ho letto che un controller è un brutto posto per metterli. quindi, come faccio a cambiare la fabbrica per lavorare con quelle chiamate API asincrone? –

+3

Solo per espandere la risposta @blesh. Controlla questo esempio più sviluppato: http://jsfiddle.net/bradbirdsall/ggmRQ/6/ – elviejo79

0

L'unico modo che funziona è includere il sdk nella pagina indice alla vecchia maniera.

Perché ho implementato la stessa soluzione da @blesh o versione estesa da @elviejo, entrambi di loro ha un problema se abbiamo una funzione che viene chiamata quando il controller viene richiamato, la probabilità che FB non è inizializzato è molto alta e questo renderà la chiamata non è riuscito durante la chiamata di una funzione da undefined :)

Spero che questo aiuterà gli altri evitando mal di testa con questo.

2

Ho scritto questo servizio angularjs-facebook. Prima di iniziarlo nel metodo di configurazione del modulo dell'app per inizializzare l'ID dell'app Facebook e altre impostazioni.

Quindi è sufficiente chiamare il servizio di Facebook da Controller e chiamare i metodi di Facebook in modo asincrono come al solito.

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

5

2015 EDIT!

Questa è una vecchia risposta.Vi suggerisco di controllare come i popolari angolari moduli su GitHub farlo o semplicemente li usano:

Vecchio risposta

A causa di problemi con le chiamate all'inizio dell'app, utilizzo il seguente approccio, che carica l'applicazione solo dopo che l'SDK è stata caricata:

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

ero perplesso su questo per un po ', ho risolto con un $ orologio

//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(); 
}); 

quando FB è stato caricato, è possibile cancellare il $ watch (che è probabilmente il migliore da fare per le prestazioni) chiamando $scope.FBListener();