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

Я новичок в AnuglarJS и уже создал с ним небольшое веб-приложение, я хотел бы использовать с ним Facebook JavaScript SDK, но с использованием лучших практик (внедрение зависимостей в контроллеры, для поддержания структуры приложения и возможности тестирования).

Я нашел это https://groups.google.com/forum/#!msg/angular/bAVx58yJyLE/Kz56Rw-cQREJ, но это очень запутанно для тех, кто плохо знаком с этой структурой (модули, сервисы и фабрики плохо объясняются, ИМХО).

Итак, как правильно использовать 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
должен ли я инициировать асинхронный 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 РЕДАКТИРОВАТЬ!

Это старый ответ. Я предлагаю вам проверить, как это делают популярные angular-модули на 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 из контроллеров и асинхронно вызывать методы 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