как правилно да инжектирате Facebook JavaScript SDK в AngularJS контролери?

Нов съм в AnuglarJS и вече създадох малко уеб приложение с него, бих искал да използвам Facebook JavaScript SDK с него, но използвайки най-добрите практики (инжектиране на зависимост към контролери, за поддържане на структурата на приложението и възможността за тестване).

Намерих това https://groups.google.com/forum/#!msg/angular/bAVx58yJyLE/Kz56Rw-cQREJ, но е много объркващо за някой нов в тази рамка (модулите, услугите и фабриките не са обяснени добре IMHO).

и така, какъв е правилният начин да използвате Facebook SDK в приложение AngularJS?


person Gal Ben-Haim    schedule 10.12.2012    source източник


Отговори (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();
       });
    };
});

Ако има някакви грешки в това, уведомете ме и аз ще потърся работния код, който имам, и ще видя какво съм пропуснал. Но това трябва да е всичко.

person Ben Lesh    schedule 10.12.2012
comment
трябва ли да стартирам async на SDK в html, както предлага Facebook, или инициализацията се извършва фабрично и html включва само sdk? - person Gal Ben-Haim; 10.12.2012
comment
кодът изглежда работи, но обвързването на данни не работи с асинхронни извиквания, опитах да използвам $q и $scope.$apply в контролера и го накарах да работи частично. но прочетох, че контролерът е лошо място за поставяне на тези. така че как да променя фабриката, за да работи с тези асинхронни API извиквания? - person Gal Ben-Haim; 11.12.2012
comment
Само за да разширя отговора на @blesh. Вижте този по-разработен пример: jsfiddle.net/bradbirdsall/ggmRQ/6 - person elviejo79; 14.02.2013

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));
person hugo der hungrige    schedule 21.09.2013

Написах тази услуга angularjs-facebook. Първо го инициализирате в метода за конфигуриране на модула на приложението, за да инициализирате идентификатора на приложението във Facebook и други настройки.

След това просто се наслаждавайте на извикването на услугата Facebook от Controllers и извикването на методите на Facebook асинхронни, както обикновено.

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

person Ciul    schedule 18.08.2013

Единственият начин, който работи, е включването на sdk във вашата индексна страница по стария начин.

Тъй като внедрих същото решение от @blesh или разширена версия от @elviejo, и двете имат проблем, ако имаме функция, която се извиква при извикване на контролера, шансът FB да не се инициализира е много голям и това ще направи повикването неуспешно при извикване на функция от undefined :)

Надяваме се, че това ще помогне на другите да избегнат главоболие с това.

person Dzung Nguyen    schedule 06.05.2013

Бях объркан от това за известно време, реших го с $watch

//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 е зареден, можете да изчистите $watch (което вероятно е най-добре да направите за производителност), като извикате $scope.FBListener();

person Max    schedule 07.10.2016