加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在angular 2打字稿中导入gapi.auth2

发布时间:2020-12-17 08:00:15 所属栏目:安全 来源:网络整理
导读:我试图在typescript中从谷歌gapi.auth2导入一些类或函数.但是下面的代码永远不会工作,即使我在typings目录中正确添加了gapi.auth2类型. 从’gapi.auth2’导入{GoogleAuth}; 我总是有错误: 错误TS2307:找不到模块’gapi.auth2′ 我应该使用一些相对目录搜索
我试图在typescript中从谷歌gapi.auth2导入一些类或函数.但是下面的代码永远不会工作,即使我在typings目录中正确添加了gapi.auth2类型.

从’gapi.auth2’导入{GoogleAuth};

我总是有错误:

错误TS2307:找不到模块’gapi.auth2′

我应该使用一些相对目录搜索,例如’../../typings/gapi.auth2’?

或者也许我使用gapi的方式是完全错误的?

谢谢!

要将gapi和gapi.auth与Angular2一起使用,请使用NPM安装类型脚本定义.
npm install --save @types/gapi
npm install --save @types/gapi.auth2

这将在node_modules文件夹中安装两个软件包@types/gapi和@types/gapi.auth2,并将配置保存在package.json中.

检查node_modules文件夹以检查它们是否正确安装.如果您的Angular2应用程序名为main-app,您应该看到:

main-app/
  node_modules/
    @types/
      gapi/
      gapi.auth2/

编辑tsconfig.json以包含新的gapi和gapi.auth2类型(下面只是一个摘录):

{
  "compileOnSave": false,"compilerOptions": {
    "types": ["gapi","gapi.auth2"]
  }
}

此时我强烈建议您抓咖啡阅读Typescript Module Resolution,您可以直接跳到Node.js如何解析模块:

[…] 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.

因此,您不需要在Angular2服务或组件中(或者在您使用gapi或gapi.auth2的任何位置)添加对类型定义的引用.

但是,如果你确实添加了对gapi或gapi.auth2 TypeScript定义的引用,它必须引用使用npm install安装的.ts文件(注意,你必须保持/// oherwise你会收到错误):

/// <reference path="../../node_modules/@types/gapi/index.d.ts" />

路径是相对的,因此您的文件可能会有所不同,具体取决于.ts文件相对于安装TypeScript定义的位置.

无论是添加显式引用还是使用TypeScript的Node模块解析机制,您仍然需要在.ts文件中声明变量,以便Angular2在编译时知道窗口gapi变量.添加声明var gapi:any;到您的.ts文件,但不要将其放在类定义中.我把它放在任何进口的下方:

// 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;

查看定义本身(https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/gapi/index.d.ts),仅导出函数.相反,接口是实现细节,因此它们不会被导出,并且对命名空间外的代码不可见.

在TypeScript documentation中使用其他JavaScript库值得阅读,以了解我们在所有这些工作中获得的成果.

接下来,使用您自己的函数加载gapi客户端(可能在Angular 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
                });
         });
    });
}

这个功能非常重要,而且有充分理由……

首先,请注意我们使用配置对象调用gapi.load而不仅仅是回调.可以使用GAPI reference状态:

>库完成时调用的回调函数
加载.
>封装各种配置参数的对象
对于这种方法.只需要回调.

使用配置选项允许我们在加载库超时或仅错误时拒绝Promise.根据我的经验,加载库比初始化失败更常见 – 这就是配置对象优于回调的原因.

其次,我们正在包装gapi.load

this.zone.run(() => {
  // gapi.load
});

NgZone.run is documented和州

Running functions via zone.run allows you to reenter Angular zone from
a task that was executed outside of the Angular zone […]

这正是我们想要的,因为对gapi.load的调用离开了Angular区域.省略这一点可以留下非常时髦的结果,这些结果很难调试.

第三,loadClient()返回一个已解析的promise – 允许调用者选择如何处理gapi.load.例如,如果我们的loadClient方法属于Angular服务apiLoaderServce,则组件可以使用ngOnInit来加载gapi:

ngOnInit(): void {
    this.apiLoaderService.loadClient().then(
        result => this.apiLoaded = true,err => this.apiLoaded = false
    );
}

一旦调用了gapi.load,gapi.client就会准备就绪,您应该使用它来使用API??密钥,OAuth客户端ID,范围和API发现文档初始化JavaScript客户端:

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);
        });
    });
}

请注意我们的朋友NgZone.run再次用于确保重新进入Angular Zone.

实际上,我将loadClient()和initClient()添加到Angular服务.在高级Angular组件中(通常在app组件下方),我在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;
    });
}

最后,您需要将gapi脚本文件添加到您的文件中.

<html>
  <head>
    <script src="https://apis.google.com/js/api.js"></script>

您不能使用async或defer属性,因为在gapi加载之前,任何一个都会导致Angular 2世界进入.

<!-- This will not work. -->
<html>
  <head>
    <script async defer src="https://apis.google.com/js/api.js"></script>

我之前建议通过在/ main-app / src / assests文件夹中加载gapi library的本地缩小副本并导入以下内容来快速保持页面加载速度:

<html>
      <head>
        <script src="assets/api.js"></script>

但是,我强烈建议不要这样做. Google可能会更新https://apis.google.com/js/api.js,您的客户将会中断.我被这两次抓住了.最后,最好从//apis.google.com/js/导入并将其保留为阻止调用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读