4

我在我的Angular 2應用程序中使用Google API Javascript庫。我創建了一個注入組件的服務。下面是代碼:使用Javascript客戶端庫作爲Angular 2服務的Google API端點

import { Injectable } from '@angular/core'; 
const url = 'https://apis.google.com/js/client.js?onload=__onGoogleLoaded'; 
@Injectable() 
export class GoogleAPIService { 
public client: any; 
public calculatorService: any; 
public actionService: any; 
loadAPI: Promise<any> 
     constructor(){ 
     this.loadAPI = new Promise((resolve) => { 
      window['__onGoogleLoaded'] = (ev) => { 
      console.log('gapi loaded'); 
      resolve(window['gapi']); 
      this.client = window['gapi'].client; 
      this.loadEndPoints('{Endpoint URL}/_ah/api'); 
      } 
      this.loadScript(); 
     }); 

     } 

     doSomethingGoogley(){ 
     return this.loadAPI.then((gapi) => { 
      console.log(gapi); 
     }); 
     } 

     loadScript(){ 
     console.log('loading..') 
     let node = document.createElement('script'); 
     node.src = url; 
     node.type = 'text/javascript'; 
     document.getElementsByTagName('head')[0].appendChild(node); 

     } 

     loadEndPoints(apiRoot) { 
    // Loads the OAuth and calculatorendpoint APIs asynchronously, and triggers login 
    // when they have completed. 
    var apisToLoad; 
    var callback = function() { 
    console.log('API Loaded '+apisToLoad); 
    if (--apisToLoad == 0) { 
     //this.endpoint1= this.client.endpoint1; //Doesn't Work 
     //this.endpoint2= this.client.endpoint2; 
    } 

    } 

    apisToLoad = 3; // must match number of calls to gapi.client.load() 
    this.client.load('oauth2', 'v2', callback); 
    this.client.load('endpoint1', 'v1', callback, apiRoot); 
    this.client.load('endpoint2','v1',callback,apiRoot); 

    } 
} 

我有三個問題:

  1. 我如何獲得端點gapi.client.endpoint1作爲服務公共變量?
  2. 如何在api中調用方法?在javascript中,你可以調用gapi.client.endpoint1.method()。execute()
  3. 如何使這個服務單例?

任何幫助表示讚賞。

編輯:

這裏是服務的工作版本。我使用它作爲提供者在我的Root模塊中。因此,它在整個應用程序中以單例形式提供。

import { Injectable } from '@angular/core'; 

const url = 'https://apis.google.com/js/client.js?onload=__onGoogleLoaded'; 
const gapiOnLoaded = '__onGoogleLoaded'; 
const clientName = 'gapi'; 
const endpointhost = '[HTTPS URL FOR ENDPOINTS]'; 
const apiEndPoint = endpointhost + '/_ah/api'; 
@Injectable() 
export class GoogleAPIService { 
    private gapi: any; 
    private loadAPI: Promise<any>; 
    constructor() { 
    this.loadAPI = new Promise((resolve) => { 
     window[gapiOnLoaded] = (ev) => { 
     this.gapi = window[clientName]; 
     // Loads the OAuth and other APIs asynchronously, and triggers login 
     // when they have completed. 
     let apisToLoad; 
     let callback = function() { 
     if (--apisToLoad === 0) { 
      resolve(window[clientName]); 
      } 
     }; 
     apisToLoad = 3; // must match number of calls to gapi.client.load() 
     this.gapi.load('client:auth2', callback); 
     this.gapi.client.load('[ENDPOINT_1_NAME]', 'v1', callback, apiEndPoint); 
     this.gapi.client.load('[ENDPOINT_2_NAME]', 'v1', callback, apiEndPoint); 
     }; 
     this.loadScript(); 
    }); 
    } 

    public GetClient(): any { 
     return this.loadAPI.then((res) => { 
       return this.gapi; 
      }); 
    } 

    private loadScript() { 
    let node = document.createElement('script'); 
    node.src = url; 
    node.type = 'text/javascript'; 
    document.getElementsByTagName('head')[0].appendChild(node); 
    } 
} 

在其他服務中注入此服務。我爲每個端點創建了一個服務。

@Injectable() 
export class Endpoint1Service { 
    private gapi: any; 
    constructor(private googleApiService: GoogleAPIService) { 
    } 

    public isLoad() { 
     return this.googleApiService.GetClient().then((gapi) => { 
       this.gapi = gapi; 
       return true; 
      }); 
    } 

    public action(data: DataType){ 
     this.gapi.client.endpointname.apimethod(data).execute(); 
    } 
} 
+0

你的第一個問題是什麼意思?它看起來像你已經有一個'const url = ...'來跟蹤谷歌api網址。你想要發生什麼? –

+0

我有多個端點..所以我想分配這些單獨的公共變量..以便我可以在組件中使用它們作爲myservice.endpoint1service – Akanksha

+0

@Akanksha這幫了我很多!你有這方面的更新嗎?也許你可以發佈你的方法的最新版本從Angular 2連接到雲端點(包括你在接受答案的回覆中提到的包裝)? – jonasjuss

回答

1

服務默認爲單身。您應該在您的AppModule中使用provide,然後它將可用於您的所有組件。只要確保將其包含在組件構造函數中。

import {NgModule} from '@angular/core'; 
import {BrowserModule} from '@angular/platform-browser'; 
import {HttpModule} from '@angular/http'; 

import { AppComponent } from './app.component'; 
import { routing } from './app.routing'; 
import { GoogleService } from './google.service'; // important 

@NgModule({ 
    imports: [ 
     BrowserModule, 
     HttpModule, 
     routing, 
    ], 
    declarations: [ AppComponent], 
    providers: [ GoogleService ], // important 
    bootstrap: [ AppComponent], 
}) 
export class AppModule { 
} 

爲了使您的服務的端點提供外,您可以使用關鍵字public在調用端點上的功能的面前。要以角度2呼叫端點,您可以使用@angular/http的內置http服務。以下是一個示例服務(僅使用HTTP GET),它將爲您調用的端點返回一個Observable。

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs'; 

@Injectable() 
export class GoogleService { 

    constructor(private http: Http) { } 

    public endpoint1(): Observable<any> { 
     return this.http.get("http://endpoint.one.com"); 
    } 

    public endpoint2(): Observable<any> { 
     return this.http.get("http://endpoint.two.com"); 
    } 

} 

然後,您可以在組件中使用這樣的服務。

import { Component, OnInit } from '@angular/core'; 
import { GoogleService } from './google.service'; // important 

@Component({ 
    selector: 'app', 
    templateUrl: 'app.component.html' 
}) 
export class AppComponent implements OnInit { 
    constructor(private googleService: GoogleService) { } 

    ngOnInit() { 

     this.googleService.endpoint1().subscribe(callback1, handleError); 

     this.googleService.endpoint2().subscribe(callback2, handleError); 

    } 

    callback1(data){ 
     // do something with the data from ONE 
    } 

    callback2(data){ 
     // do something with the data from TWO 
    } 

    handleError(error: any){ 
     console.error(error); 
    } 

} 

我建議在使用this post從觀測量角大學讀了一下。

+0

謝謝,我最終爲每個端點創建了包裝。你的樣品指出我在正確的方向 – Akanksha

0

我不認爲修改DOM來加載gapi是特別好的做法。使用NPM安裝gapigapi.auth TypeScript定義可能會更好。

我已經發布瞭如何在我的回答Import gapi.auth2 in angular 2 typescript中做到這一點的說明。

+0

我同意。我最終創建了自己的服務,它打擊谷歌身份驗證網址並獲取訪問令牌。 – Akanksha

相關問題