【问题标题】:Load Google Maps JS API in component [Angular]在组件 [Angular] 中加载 Google Maps JS API
【发布时间】:2018-06-16 12:36:27
【问题描述】:

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

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

<script async defer src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initMap">
</script>

注意:我知道angular-maps。这不是一个选项。

【问题讨论】:

    标签: javascript angular google-maps google-maps-api-3


    【解决方案1】:

    解决办法是在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);
    }
    

    另见https://github.com/angular/angular/issues/4903

    更新

    <div id="map" #mapRef></div>
    

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

    【讨论】:

    • 感谢您的回答。但是callback 部分呢? api 准备好后如何收到通知?
    • 再次感谢,但上面的代码不会等待google.maps 被加载。
    • js一旦加载就会加载
    • 你能解释一下吗?我很困惑。
    • @HamidAsghari :查看此链接以查看工作演示 stackblitz.com/edit/…
    【解决方案2】:

    您可以随时使用 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
                });
            });
        }
    }
    

    组件

    //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
      }
    
      ...
    }
    

    组件 HTML

    // maps.component.html
    <div #gmap ></div>
    

    别忘了给元素添加 CSS。

    【讨论】:

    • 我不确定为什么这个答案没有被赞成。我通过查看这段代码得到了我的解决方案——但我在 ngOnInit() 的 app.component.ts 中实现了。干杯!
    • 替换“地图:google.maps.Map;”与“地图:任何;”以防止类型错误。还添加“窗口”。在任何“google.maps”之前。
    • @desmati,就是在打字稿中使用@types/googlemaps。它将支持 google API 的自动完成。如果您遇到错误,您可以安装 @types/googlemaps。
    • 主要答案对我不起作用,但这有效,只能通过 id 添加到您的 css:#map { height: 100vh;宽度:100vw;然后添加到node.src变量:node.src +='&key=YOUR_KEY';
    • 我想这个人需要这个代码,也知道 CSS。关于密钥,谷歌改变了他们的政策,需要 API 密钥。我会更新上面的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 2017-08-19
    • 1970-01-01
    • 2020-10-28
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多