gapi
und gapi.auth
mit Angular2 zu verwenden, um die Art Skript-Definitionen NPM installieren.
npm install --save @types/gapi
npm install --save @types/gapi.auth2
Dies wird zwei Pakete, @types/gapi und @types/gapi.auth2 zum node_modules
Ordner installieren und die Konfiguration in package.json
speichern.
Überprüfen Sie Ihre node_modules
Ordner, um zu überprüfen, ob sie korrekt installiert sind. Wenn Ihr Angular2 App Haupt-App genannt, sollten Sie sehen:
main-app/
node_modules/
@types/
gapi/
gapi.auth2/
bearbeiten tsconfig.json
neue gapi
und gapi.auth2
Typen umfassen (unten ist nur ein Auszug):
{
"compileOnSave": false,
"compilerOptions": {
"types": ["gapi", "gapi.auth2"]
}
}
An diesem Punkt ist hoch empfehlen einen Kaffee greifen und Lese Typescript Module Resolution, können Sie direkt zu überspringen Wie Node.js Module löst:
[...] resolution for a non-relative module name is performed differently. Node will look for your modules in special folders named node_modules
. A node_modules
folder can be on the same level as the current file, or higher up in the directory chain. Node will walk up the directory chain, looking through each node_modules
until it finds the module you tried to load.
Aus diesem Grund sollten Sie in Ihrem Angular2 Service oder Ihrer Komponente (oder wo immer Sie gapi
oder gapi.auth2
verwenden) keinen Verweis auf die Typdefinitionen hinzufügen müssen.
Wenn Sie jedoch auf die gapi
oder gapi.auth2
Typoskript Definitionen eine Referenz zu tun hinzuzufügen, muss er die .ts
Datei verweisen installiert mit npm install
(beachten Sie, Sie ///
halten müssen oherwise Sie einen Fehler finden):
/// <reference path="../../node_modules/@types/gapi/index.d.ts" />
Der Pfad ist relativ, so dass Sie davon abweichen können, je nachdem, wo sich Ihre .ts
-Datei in Bezug auf die Stelle befindet, an der Sie die TypeScript-Definitionen installiert haben.
Ob Sie einen expliziten Verweis hinzugefügt oder den Typskript-Node-Modul-Auflösungsmechanismus verwendet haben, müssen Sie Ihre Variablen immer noch in Ihrer .ts
-Datei deklarieren, damit Angular2 die Window-Gapi-Variable zur Kompilierzeit kennt.Fügen Sie declare var gapi: any;
zu Ihrer .ts
Datei hinzu, aber tun Sie nicht platzieren Sie es innerhalb einer Klassendefinition. Ich habe meine knapp unter irgendwelchen Importen:
// You may not have this explicit reference.
/// <reference path="../../node_modules/@types/gapi/index.d.ts" />
import { NgZone, Injectable, Optional } from '@angular/core';
declare var gapi: any;
bei den Definitionen der Suche selbst (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/gapi/index.d.ts) werden nur Funktionen exportiert. Umgekehrt sind die Schnittstellen Implementierungsdetails, so dass sie nicht exportiert werden und für Code außerhalb des Namensraums nicht sichtbar sind.
Arbeiten mit anderen JavaScript-Bibliotheken in TypeScript documentation ist lesenswert, um zu verstehen, was wir mit all dieser Arbeit bekommen.
Als nächstes laden Sie die gapi
Client mit Ihrer eigenen Funktion (möglich in einem Winkel Service):
loadClient(): Promise<any> {
return new Promise((resolve, reject) => {
this.zone.run(() => {
gapi.load('client', {
callback: resolve,
onerror: reject,
timeout: 1000, // 5 seconds.
ontimeout: reject
});
});
});
}
Diese Funktion ist nicht trivial, und das aus gutem Grund ...
Zum einen Vermerk Wir rufen gapi.load mit einem Konfigurationsobjekt und nicht nur einen Rückruf. Die GAPI reference Zustände können entweder verwendet werden:
- Eine Rückruffunktion, die aufgerufen wird, wenn die Bibliotheken Laden beendet haben.
- Ein Objekt, das die verschiedenen Konfigurationsparameter für diese Methode einkapselt. Nur ein Rückruf ist erforderlich.
eine Konfigurationsoption verwenden können wir das Versprechen ablehnen, wenn die Bibliothek mal-out Laden, oder einfach nur Fehler. Nach meiner Erfahrung schlägt das Laden der Bibliothek häufiger fehl als das Initialisieren - weshalb das Konfigurationsobjekt besser ist als nur ein Callback.
Zweitens, wir wickeln gapi.load
in
this.zone.run(() => {
// gapi.load
});
NgZone.run is documented und Staaten
Running functions via zone.run
allows you to reenter Angular zone from a task that was executed outside of the Angular zone [...]
Das ist genau das, was wir wollen, da der Aufruf an gapi.load
die Winkelzone verlässt. Wenn man dies auslässt, kann das zu sehr funky Ergebnissen führen, die schwer zu debuggen sind.
Drittens gibt loadClient()
ein Versprechen zurück, das aufgelöst wird - dem Anrufer zu ermöglichen, zu wählen, wie sie mit gapi.load
umgehen. Zum Beispiel, wenn unsere loadClient
Verfahren zu einem Winkel Dienst gehören, apiLoaderServce
kann eine Komponente ngOnInit
verwendet gapi
laden:
ngOnInit(): void {
this.apiLoaderService.loadClient().then(
result => this.apiLoaded = true,
err => this.apiLoaded = false
);
}
Sobald gapi.load
aufgerufen wurde, gapi.client
bereit sein wird, und Sie sollten es verwenden, um den JavaScript-Client initialisiert mit Ihnen API-Schlüssel, OAuth-Client-ID, Umfang und API-Erkennungs-Dokument (e):
initClient(): Promise<any> {
var API_KEY = // Your API key.
var DISCOVERY_DOC = // Your discovery doc URL.
var initObj = {
'apiKey': API_KEY,
'discoveryDocs': [DISCOVERY_DOC],
};
return new Promise((resolve, reject) => {
this.zone.run(() => {
gapi.client.init(initObj).then(resolve, reject);
});
});
}
Hinweis unser Freund NgZone.run wird wieder verwendet, um die Winkelzone, um sicherzustellen, erneut eingegeben.In der Praxis füge ich loadClient()
und initClient()
zu einem Angular Service hinzu. In einer High-Level-Winkelkomponente (in der Regel nur unter der App-Komponente) I geladen und initialisiert in ngOnInit
:
ngOnInit(): void {
this.apiLoaderService.loadClient().then(
result => {
this.apiLoaded = true;
return this.apiLoaderService.initClient()
},
err => {
this.apiFailed = true;
}
).then(result => {
this.apiReady = true;
}, err => {
this.apiFailed = true;
});
}
Schließlich müssen Sie die gapi Skript-Datei auf Ihre Datei hinzuzufügen.
<html>
<head>
<script src="https://apis.google.com/js/api.js"></script>
müssen Sie nicht die async
oderdefer
Attribute verwenden, da entweder Angular 2 Welt verursachen wird, bevor gapi geladen ist einzugeben.
<!-- This will not work. -->
<html>
<head>
<script async defer src="https://apis.google.com/js/api.js"></script>
ich vorher hatte vorgeschlagen Seitenladegeschwindigkeit schnell zu halten durch eine lokale, minimierte Kopie des gapi library im /main-app/src/assests
Ordner Laden und Importieren:
<html>
<head>
<script src="assets/api.js"></script>
jedoch ich stark empfehlen nicht tun dies. Google aktualisiert möglicherweise https://apis.google.com/js/api.js und Ihr Client wird beschädigt. Ich bin zweimal davon überrascht worden. Am Ende war es besser, einfach von zu importieren und es als Blockierruf zu behalten.
Werfen Sie einen Blick auf die Importanleitung https://www.typescriptlang.org/docs/handbook/module-resolution.html – AngJobs