2016-05-11 2 views
3

J'essaie d'utiliser FB SDK à partir d'un projet Angular2 créé avec la nouvelle CLI angulaire. J'ai créé le service suivant pour initialiser la bibliothèque Facebook, ajouté les typages fbsdk et tout compile mais je ne peux pas accéder à la variable globale FB de n'importe où dans le projet mais la fonction "winwow.fbAsyncInit". Je peux vérifier l'objet FB de la console parfaitement, mais je ne peux pas y accéder à partir du code NG2. Toute idée d'où le problème pourrait être?Comment accéder à FB global à partir du service Angular2?

import { Injectable, OnInit } from '@angular/core' 
import { FACEBOOK_APPID } from '../constants' 

@Injectable() 
export class fbService implements OnInit{ 
    constructor(){} 
    ngOnInit(){ 
    if (!window.fbAsyncInit) { 
     window.fbAsyncInit = function() { 
      FB.init({ 
       appId: FACEBOOK_APPID, 
       xfbml: false, 
       version: 'v2.6' 
      }); 
      FB.api("/me",null,()=>{}) 
      console.log(FB) 
     }; 
    } 
    this.initFB()   
} 
initFB(){ 
    var js, id = 'facebook-jssdk', ref = document.getElementsByTagName('script')[0]; 
    if (document.getElementById(id)) { 
     return; 
    } 
    js = document.createElement('script'); 
    js.id = id; 
    js.async = true; 
    js.src = "//connect.facebook.net/en_US/sdk.js"; 
    ref.parentNode.insertBefore(js, ref); 
} 
getPost(page:string){ 
    FB.api(`/${page}/feed?limit=1`,null,(response)=>{console.log(response)}) 
} 
} 
+0

que diriez-vous ajouter 'élément script' en html statique. –

+0

Après quelques tests, il semble lié au cycle de vie ng2. Si je mets la fonction init sur le constructeur de fbService, je peux accéder au FB global à partir de n'importe quel évènement de clic de bouton ou alors une fois que tout le dom est chargé. Si j'essaie d'y accéder à partir d'un événement OnInit de composant, le FB n'est pas encore défini. – Perseoh

Répondre

0

La clé est dans l'appel à this.zone.run(callback) pour envelopper le rappel et le réinsérer dans le cycle de vie 2 angulaire.

Je initialise le SDK dans le constructeur de service, ce qui peut introduire un certain retard par rapport au chargement immédiat. Je n'ai pas encore trouvé de solution de contournement.

Je n'ai pas encore décidé si je fournirai un accesseur à FB une fois initialisé ou les méthodes d'emballage, je vous laisse.

@Injectable() 
export class FbsdkService { 
    public ready = new BehaviorSubject<boolean>(false); 

    constructor(
     private zone: NgZone) { 
     this.loadSdkAsync(() => { 
      FB.init({ 
       appId: "XXXXXXXXXXX", 
       status: false, 
       xfbml: false, 
       version: "v2.7" 
      }); 
      this.ready.next(true); 
     }); 
    } 

    loadSdkAsync(callback:() => void) { 
     window.fbAsyncInit =() => this.zone.run(callback); 
     // Load the Facebook SDK asynchronously 
     const s = "script"; 
     const id = "facebook-jssdk"; 
     var js, fjs = document.getElementsByTagName(s)[0]; 
     if (document.getElementById(id)) return; 
     js = document.createElement(s); js.id = id; 
     js.src = "//connect.facebook.net/en_US/sdk.js"; 
     fjs.parentNode.insertBefore(js, fjs) 
    } 
} 
0

j'avais problème similaire et cette source m'a aidé

Lot- Building CrossPlatform Desktop Applications with Electron
import { Injectable, NgZone } from '@angular/core'; 
import { BehaviorSubject } from "rxjs/Rx"; 
import { Http } from '@angular/http'; 

declare var FB: any; 

@Injectable() 
export class FbsdkService { 
    public ready = new BehaviorSubject<boolean>(false); 
    public endpointBase = 'http://graph.facebook.com'; 
    constructor(private zone: NgZone, private http: Http) { 
    } 

    public loadSdk() { 
     this.loadAsync(() => { }); 
    } 

    public loadAsync(callback:() => void) { 
     window.fbAsyncInit =() => this.zone.run(callback); 

     const s = "script"; 
     const id = "facebook-jssdk"; 
     var js: any, fjs = document.getElementsByTagName(s)[0]; 
     if (document.getElementById(id)) return; 
     js = document.createElement(s); 
     js.id = id; 
     js.src = "//connect.facebook.net/en_US/sdk.js"; 
     fjs.parentNode.insertBefore(js, fjs); 
    } 

    public getLoginStatus() { 
     FB.getLoginStatus((response: any) => { console.log(response); }); 
    } 

    public getProfile() { 
     return new Promise((resolve, reject) => { 
      let fields = [ 
       "id", "name", "email", "cover", "birthday" 
      ]; 
      FB.api(`/me?fields=${fields.toString()}`, (response: any) => { 
       resolve(response); 
      }); 
     }); 
    } 

}