入门 - 如何使用带有angular-cli的Google maps api

时间:2017-03-15 17:08:27

标签: google-maps angular typescript angular-cli

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

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

从我的研究看起来我首先安装所需的类型脚本文件。 所以对于Google地图,我做了npm install --save @types/google-maps。 现在,我是否需要将此模块导入到我的角度应用程序中,方法是将其包含在app.module.ts中?在进口数组?或者它现在全球可用?

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

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

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

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

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

我如何使用刚刚安装的Google图谱的打字稿版本来完成这项工作?

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

2 个答案:

答案 0 :(得分:16)

@Steve G.指出的agm项目提供了一个很好的起点,但出于某种原因(比如管理自己的请求策略),您可能想要制作自己的类型包装器。 我在这里是如何用Angular Cli做的:

第一步:

npm i --save @types/googlemaps

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

"types": ["googlemaps"]

最后写下你的打字稿:

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

}

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

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

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

答案 1 :(得分:0)

我在部件上使用AGM也遇到了麻烦,然后尝试了nu-maps,也遇到了麻烦。

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

  • 简单
  • 有据可查
  • 不依赖于一些不合并拉取请求的人
  • 有效!