2012-08-07 12 views
11

Ich möchte FB SDK mit require.js laden.mit require.js mit FB SDK

mein Testfall ist so etwas wie folgt aus:

test.js:

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

Ich mag würde test.js haben laufen erst nach FB SDK geladen wird, und haben FB bereit es.

Irgendwelche Gedanken darüber, wie dies erreicht werden kann? Was soll mein Wrapper (libs/facebook/fb.js) haben?

+1

Sieht aus wie Facebook diese schließlich angesprochen hat, ihre Lösung für einige ziemlich ähnlich sieht aus die Antworten auf diese Frage. https://developers.facebook.com/docs/howto/javascript/requirejs/ – the0ther

Antwort

10

Es scheint nicht, dass die FB API ein AMD-Modul ist, also definiert sie sich nicht in einer Weise, an die RequireJS gewöhnt ist. Sie müssen die FB-API mit require.config shimmen. Ich nehme an, test.js ist das Skript, das Sie als Datenhauptwert für RequireJS angegeben haben.

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

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

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

Könnten Sie vielleicht mehr Details zu dieser Antwort hinzufügen? Was sollte libs/facebook/fb enthalten? Der 'FB.init()' Code? Ein Verweis auf "https: // connect.facebook.net/de_DE/all/debug.js"? –

+1

libs/facebook/fb ist der Pfad zum fb-Modul oder in diesem Fall zum fb.js-Datei. RequireJS geht davon aus, dass alles ein Modul ist und erfordert nicht, dass Sie den JS-Teil des Dateipfads einschließen. Es wird das selbst erkennen. –

+0

Sorry, immer noch ein bisschen verwirrt. Meinst du es ist eine wörtliche Kopie dieser Datei: https://connect.facebook.net/en_US/all.js? Wenn ja, wohin geht der Init-Code? Das Laden der Bibliothek reicht nicht aus, um 'FB.api()' ' –

3

Oder den Init-Code in einem Modul wickeln (die Probe verwendet 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

Es sieht so aus, als käme der Code zum Hinzufügen des 'fb-root'-Elements hier zu spät, da das Facebook SDK nach dem Laden nach diesem div sucht und es automatisch erstellt, falls es nicht bereits existiert. –

+0

könnten Sie diesen Code vielleicht etwas erklären? Verhindert dies, dass "FB" zu "window" hinzugefügt wird? Ist @ DrakeHamptons Kommentar korrekt? Irgendwelche anderen Auswirkungen? –

+0

Ich mache etwas sehr ähnliches (sans Dojo), aber FB ist nicht verfügbar zu der Zeit, wenn ich 'FB.init()' –

1

Aufbauend auf voidstate's und Dzulqarnain Nasir's Antworten, hier ist der Code, den ich an meinem Projekt am Ende mit.

Der Teil, der mich am meisten stolperte war, dass FB.init() scheinbar asynchron ist. Bei dem Versuch, die callback() (ohne FB.getLoginStatus), FB wurde noch nicht initialisiert, und ich bekam "An active access token must be used to query information about the current user." Fehler.

RequireJS Shim 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 Modul 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); 
     }    
    }; 

}); 

Diese noch initialisieren nicht ganz die ursprüngliche Frage der gewünschten Nutzung adressieren.

Code des OP vielleicht neu geschrieben werden können als:

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

Das ist nicht ganz so cleanas ursprüngliche Konzept des OP, aber es ist das Beste, was ich herausfinden konnte. Wenn jemand welche hat, würde ich gerne Feedback oder Ratschläge dazu bekommen, wie ich meinen Ansatz verbessern kann. Ich bin immer noch sehr neu in RequireJS. Hier

3

ist eine Dokumentation von 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']); 

und fügen Sie dann das Modul wie folgt aus:

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

ein Editieren abgelehnt wurde kommentiert, dass es einen Tippfehler in facebooks Handbuch gibt 'require ([ 'fb']); 'sollte sein' (['facebook']); '. Das mag wahr sein, also ist es einen Kommentar wert. – Popnoodles

+0

@Popnoodles: "erfordern (['fb']);" ist richtig. fb ist der Name der von Ihnen erstellten Moduldatei. – nfplee

Verwandte Themen