在组件[Angular]中加载Google Maps JS API

Ham*_*ari 4 javascript google-maps google-maps-api-3 angular

如何js从Angular组件中的url 加载外部文件?

具体来说,我正在尝试加载google-maps-api我的角度项目.目前,我正在这样做index.html:

<script async defer src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initMap">
</script>
Run Code Online (Sandbox Code Playgroud)

注意:我知道angular-maps.那不是一个选择.

Joh*_*ohn 8

您可以随时使用Promise异步加载Google API.

// map-loader.service.ts
import ...
declare var window: any;

@Injectable()
export class MapLoader {

    private static promise;
    map: google.maps.Map;

    public static load() {
        if (!MapLoader.promise) { // load once
            MapLoader.promise = new Promise((resolve) => {
                window['__onGapiLoaded'] = (ev) => {
                    console.log('gapi loaded')
                    resolve(window.gapi);
                }
                console.log('loading..')
                const node = document.createElement('script');
                node.src = 'https://maps.googleapis.com/maps/api/js?key=<YOUR _API_KEY>&callback=__onGapiLoaded';
                node.type = 'text/javascript';
                document.getElementsByTagName('head')[0].appendChild(node);
            });
        }

        return MapLoader.promise;
    }

    initMap(gmapElement, lat, lng) {

        return MapLoader.load().then((gapi) => {
            this.map = new google.maps.Map(gmapElement.nativeElement, {
                center: new google.maps.LatLng(lat, lng),
                zoom: 12
            });
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

零件

//maps.component.ts

...
@Component({
  selector: 'maps-page',
  templateUrl: './maps.component.html'
})
export class MapsComponent implements OnInit {       

  @ViewChild('gmap') gmapElement: any;
  constructor(public mapLoader: MapLoader) { }

  ngOnInit() {

      this.mapLoader.initMap(this.gmapElement, -37.81, 144.96)  // await until gapi load
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

组件HTML

// maps.component.html
<div #gmap ></div>
Run Code Online (Sandbox Code Playgroud)

不要忘记将CSS添加到元素中.

  • 我不确定为什么这个答案没有被投票.我通过查看这段代码得到了我的解决方案 - 但是我在ngOnInit()中的app.component.ts中实现了.干杯! (4认同)

san*_*ngh 7

解决方案是动态创建脚本标记 ngAfterViewInit()

import { DOCUMENT } from '@angular/common';
...

constructor(private @Inject(DOCUMENT) document, 
            private elementRef:ElementRef) {};

ngAfterViewInit() {
  var s = this.document.createElement("script");
  s.type = "text/javascript";
  s.src = "https://maps.googleapis.com/maps/api/js?key=API_KEY";
  this.elementRef.nativeElement.appendChild(s);
}
Run Code Online (Sandbox Code Playgroud)

ngAfterViewInit() ngAfterViewInit()

更新

<div id="map" #mapRef></div>
Run Code Online (Sandbox Code Playgroud)
export class GoogleComponent implements OnInit {
      @ViewChild("mapRef") mapRef: ElementRef;
      constructor() { }
    
      ngOnInit() {
        this.showMap();
      }
    
      showMap() {
        console.log(this.mapRef.nativeElement);
        const location = { lat: 28.5355, lng: 77.3910 };
        var options = {
          center: location,
          zoom: 8
        }
    
        const map = new google.maps.Map(this.mapRef.nativeElement, options);
        this.addMarket(map, location);
      }
      addMarket(pos, map) {
        return new google.maps.Marker({
          position: pos,
          map: map,
        });
      }
    
    }




   
Run Code Online (Sandbox Code Playgroud)