typescript 入门 - 如何在 angular-cli 中使用 Google 地图 API

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42816363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:21:14  来源:igfitidea点击:

Getting started - How to use Google maps api with angular-cli

google-mapsangulartypescriptangular-cli

提问by MAhsan

I recently got started with ng2. So I created a project using angular-cli, then I realized I need some third party modules. Such as Google maps api, lodash, jquery...etc. I know the basics of Typescript, but how do I use these modules in an Angular2 app? Also, I want to use just the library, for example Google maps api, not any existing ng2 module/component someone else made ontop of the Google maps api - For the sake of learning.

我最近开始使用 ng2。所以我使用 angular-cli 创建了一个项目,然后我意识到我需要一些第三方模块。比如谷歌地图api、lodash、jquery...等。我知道 Typescript 的基础知识,但是如何在 Angular2 应用程序中使用这些模块?另外,我只想使用库,例如​​谷歌地图 api,而不是其他人在谷歌地图 api 上制作的任何现有的 ng2 模块/组件 - 为了学习。

Previously, with just JS I would include the js file and reference the api documentation to know which methods to reference and build my app. Now with Angular2, what steps should I take to do the same?

以前,仅使用 JS,我会包含 js 文件并参考 api 文档以了解要引用和构建我的应用程序的方法。现在使用 Angular2,我应该采取哪些步骤来做同样的事情?

From my research it looks like I first install the type script files needed. so for Google maps I did npm install --save @types/google-maps. Now, do I need to import this module into my angular app by including it in app.module.ts? In the imports array? Or is it now globally available?

从我的研究看来,我首先安装了所需的类型脚本文件。所以对于谷歌地图我做了npm install --save @types/google-maps。现在,我是否需要通过将它包含在 app.module.ts 中来将此模块导入到我的 angular 应用程序中?在导入数组中?还是现在全球可用?

One source mentioned installing it with npm and in my angular-cli.json including a reference to that library in the scripts array. like so:

一个消息来源提到使用 npm 安装它,并在我的 angular-cli.json 中包括对脚本数组中该库的引用。像这样:

"scripts": ['./node_modules/googlemaps/googemaps.min.js'],

Which method to use in installing the google maps api? I would think Typescript might be the way to go since the rest of the Angular app is going to be written in Typescript.

安装谷歌地图api使用哪种方法?我认为 Typescript 可能是要走的路,因为 Angular 应用程序的其余部分将用 Typescript 编写。

Now in my app.component.ts, I want to create a simple map using the typescript I installed. How would I do so? The google maps api says to create a new instance of the map like so.

现在在我的 app.component.ts 中,我想使用我安装的打字稿创建一个简单的地图。我该怎么做?谷歌地图 api 说要像这样创建地图的新实例。

var map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.397, lng: 150.644},
          scrollwheel: false,
          zoom: 8
        });

How would I do that with the typescript version of Googlemaps I just installed?

我将如何使用我刚刚安装的 Googlemaps 的打字稿版本做到这一点?

Would a typescript version of Googlemaps have all the same methods as the original API? Do typescripts of popular JS libraries have a documentation site I can reference?

Googlemaps 的打字稿版本是否具有与原始 API 相同的方法?流行 JS 库的打字稿是否有我可以参考的文档站点?

回答by Karbos 538

The agmproject pointed by @Steve G. give a good starting point, but for some reason (like manage your own request policy) you may want to make your own typed wrapper. Here how I did it with Angular Cli :

AGM项目指向的@Steve G.给予出发点的好,但由于某种原因(比如管理自己的请求策略),你可能想使自己的类型的包装。这是我如何使用 Angular Cli 做到的:

First step :

第一步 :

npm i --save @types/googlemaps

Secondly add the types to your tsconfig.app.json:

其次将类型添加到您的tsconfig.app.json

"types": ["googlemaps"]

Finally write your typescript :

最后写下你的打字稿:

//nothing to import here

//Replace this by anything without an ID_KEY
const getScriptSrc = (callbackName) => {
  return `https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=${callbackName}`;
}

export class GMapService {

  private map: google.maps.Map;
  private geocoder: google.maps.Geocoder;
  private scriptLoadingPromise: Promise<void>;

  constructor() {
        //Loading script
        this.loadScriptLoadingPromise();
        //Loading other components
        this.onReady().then(() => {
          this.geocoder = new google.maps.Geocoder();
        });
  }

  onReady(): Promise<void> {
    return this.scriptLoadingPromise;
  }

  initMap(mapHtmlElement: HTMLElement, options: google.maps.MapOptions): Promise<google.maps.Map> {
    return this.onReady().then(() => {
      return this.map = new google.maps.Map(mapHtmlElement, options);
    });
  }

  private loadScriptLoadingPromise() {
    const script = window.document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.defer = true;
    const callbackName: string = 'UNIQUE_NAME_HERE';
    script.src = getScriptSrc(callbackName);
    this.scriptLoadingPromise = new Promise<void>((resolve: Function, reject: Function) => {
      (<any>window)[callbackName] = () => { resolve(); };

      script.onerror = (error: Event) => { reject(error); };
    });
    window.document.body.appendChild(script);
  }

  /** Exemple of wrapped to promise API */
  geocode(address: string | google.maps.GeocoderRequest): Promise<google.maps.GeocoderResult[]> {
    return this.onReady().then(() => {
      this.geocoder.geocode(typeof address == "google.maps.GeocoderRequest" ? address: {address: address},
          (results: google.maps.GeocoderResult[], status: google.maps.GeocoderStatus) => {
            if(status == google.maps.GeocoderStatus.OK) {
              return results;
            } else {
              throw new Error(status.toString());
            }
      });
    });
  });

}

And so your map component will look like this :

因此,您的地图组件将如下所示:

@Component({
  selector: 'app-gmap-wrapper',
  template: '<div #map style="width:400px; height:300px">loading...</div>'
})
export class GMapWrapperComponent implements OnInit {
    @ViewChild('map') mapRef: ElementRef;

    constructor(private gmapService: GMapService) { }

    ngOnInit() {
      this.gmapService.initMap(this.mapRef.nativeElement, {
        center: {lat: 1234.1234, lng: 1234.1234},
        scrollwheel: true,
        zoom: 8
      });
    }
}

This code should be better without the namespace google.mapsin prefix of all types. Maybe any suggestion ?

如果没有google.maps所有类型的前缀中的命名空间,此代码应该会更好。也许有什么建议?

回答by R.S

I also had troubles with AGM in componets, then i tried nu-maps and also there I had troubles.

我在组件中的 AGM 也遇到了麻烦,然后我尝试了 nu-maps,在那里我也遇到了麻烦。

So I used plain google api javascript and I think its better: https://cloud.google.com/maps-platform/?hl=de

所以我使用了普通的 google api javascript,我认为它更好:https: //cloud.google.com/maps-platform/?hl=de

  • simple
  • good documented
  • not dependent of some guys who do not merge the pull requests
  • it works!
  • 简单的
  • 有据可查
  • 不依赖于一些不合并拉取请求的人
  • 有用!