2012-08-07 42 views
11

Me gustaría cargar FB SDK usando require.js.usando require.js con FB SDK

mi caso de prueba es algo como esto:

Test.js:

require([   
    'libs/facebook/fb' 
    ], function(FB){ 
    FB.api("/me", function(){}); 
)); 

me gustaría tener Test.js funcionar sólo después de que se carga FB SDK, y tienen listo para FB eso.

¿Alguna idea sobre cómo se puede lograr esto? ¿Qué debería tener mi envoltorio (libs/facebook/fb.js)?

+1

Parece que Facebook ha abordado finalmente esto, su solución es muy similar a algunos de las respuestas a esta pregunta. https://developers.facebook.com/docs/howto/javascript/requirejs/ – the0ther

Respuesta

10

No parece que la API FB sea un módulo AMD, por lo que no se define de manera tal que RequireJS está acostumbrado. Deberá ajustar la API de FB utilizando require.config. Supongo que test.js es el script que ha proporcionado como valor principal de datos para RequireJS.

require.config({ 
    shim: { 
     'facebook' : { 
      exports: 'FB' 
     } 
    }, 

    paths: { 
     'facebook' : 'libs/facebook/fb' 
    } 
}); 

require(['facebook'], function(FB){ 
    FB.api('/me', function(){}); 
}); 
+0

¿podría agregar más detalles a esta respuesta? ¿Qué debería contener libs/facebook/fb? El código 'FB.init()'? Una referencia a 'https: // connect.facebook.net/en_US/all/debug.js'? –

+1

libs/facebook/fb es la ruta al módulo fb, o en este caso el fb.js archivo. RequireJS supone que todo es un módulo y no requiere que incluya la parte .js de la ruta del archivo. Lo detectará por sí mismo. –

+0

Lo siento, todavía estoy un poco confundido. ¿Quiere decir que es una copia literal de este archivo: https://connect.facebook.net/en_US/all.js? Si es así, ¿a dónde va el código de inicio? Simplemente cargar la biblioteca no es suficiente para llamar a 'FB.api()' –

3

o envuelva el código de inicio en un módulo (el ejemplo utiliza Dojo):

define('facebook', 
    [ 'dojo/dom-construct', 
     'dojo/_base/window', 
     'https://connect.facebook.net/en_US/all/debug.js' ], // remove "/debug" in live env 
    function(domConstruct, win) 
    { 

     // add Facebook div 
     domConstruct.create('div', { id:'fb-root' }, win.body(), 'first'); 

     // init the Facebook JS SDK 
     FB.init({ 
      appId: '1234567890', // App ID from the App Dashboard 
      channelUrl: '//' + window.location.hostname + '/facebook-channel.html', // Channel File for x-domain communication 
      status: true, // check the login status upon init? 
      cookie: true, // set sessions cookies to allow your server to access the session? 
      xfbml: true // parse XFBML tags on this page? 
     }); 


     // Additional initialization code such as adding Event Listeners goes here 
     console.log('Facebook ready'); 

     return FB; 
    } 
); 
+0

Parece que el código aquí para agregar el elemento 'fb-root' aquí se ejecuta demasiado tarde, ya que el SDK de Facebook busca ese div después de la carga y lo crea automáticamente si aún no existe. –

+0

¿podría explicar este código un poco? ¿Esto evita que 'FB' se agregue a' window'? ¿El comentario de @ DrakeHampton es correcto? ¿Alguna otra implicación? –

+0

Estoy haciendo algo muy similar a esto (sans Dojo) pero FB no está disponible en el momento en que invoco 'FB.init()' –

1

Basándose en voidstate's y Dzulqarnain Nasir's respuestas, aquí está el código que terminé usando en mi proyecto.

La parte que más me ha tropezado es que FB.init() es aparentemente asíncrono. Al tratar de invocar el callback() (sin FB.getLoginStatus), FB aún no se había inicializado y recibía los errores "An active access token must be used to query information about the current user.".

RequireJS Calce Config

require.config({ 
    // paths: { 'facebookSDK': '//connect.facebook.net/en_US/all/debug' }, // development 
    paths: { 'facebookSDK': '//connect.facebook.net/en_US/all' }, // production 
    shim: { 'facebookSDK': { exports: 'FB' } } 
}); 

AMD Módulo Para inicializar Facebook JS SDK

define(['facebookSDK'], function (FB) { 
    'use strict'; 

    return function (settings, callback) { 
     var args = { 
      appId: settings.appId, 
      channelUrl: settings.channelUrl, 
      status: true, 
      cookie: true, 
      xfbml: true 
     }; 

     console.log('Calling FB.init:', args); 
     FB.init(args); 

     if (callback && typeof (callback) === "function") { 
      // callback() // does not work, FB.init() is not yet finished 
      FB.getLoginStatus(callback); 
     }    
    }; 

}); 

Esto todavía no acaba de dirección de uso deseado de la pregunta original. código

de OP tal vez podría ser reescrita como:

require(['libs/facebook/fb'], // where fb.js holds my above Module 
    function(FBinit){ 
    FBinit({ 
     appId: appId, 
     channelUrl: channelUrl 
    }, function(){ 
     FB.api("/me", function(){}); 
    }); 
    } 
); 

Esto no es tan cleanas concepto original de OP, pero es el mejor que he podido averiguar. Si alguien tiene alguno, me gustaría recibir algunos comentarios o consejos sobre cómo mejorar mi enfoque. Todavía soy muy nuevo en RequireJS.

3

Aquí es una documentación de Facebook: https://developers.facebook.com/docs/javascript/howto/requirejs/

require.config({ 
    shim: { 
    'facebook' : { 
     export: 'FB' 
    } 
    }, 
    paths: { 
    'facebook': '//connect.facebook.net/en_US/all' 
    } 
}) 
require(['fb']); 

y luego añadir el módulo de la siguiente manera:

define(['facebook'], function(){ 
    FB.init({ 
    appId  : 'YOUR_APP_ID', 
    channelUrl : '//yourdomain.com/channel.html' 
    }); 
    FB.getLoginStatus(function(response) { 
    console.log(response); 
    }); 
}); 
+1

Se rechazó una edición al comentar que hay un error en el manual de Facebook que dice 'require ([ 'fb']); 'debe ser' require (['facebook']); '. Esto puede ser cierto, así que es digno de un comentario. – Popnoodles

+0

@Popnoodles: "require (['fb']);" es correcto. fb es el nombre del archivo de módulo que usted crea. – nfplee

Cuestiones relacionadas