当前位置: 首页 > 面试题库 >

AngularJS-在指令中为多个地图加载Google Map脚本异步

穆仲卿
2023-03-14
问题内容

我目前正在尝试在单个页面上加载多个Google地图。我不希望将Google Map
API脚本包含到HTML代码中,因为我不希望加载脚本,除非地图位于当前页面中。我希望在一个指令中调用我的地图,该指令还将执行google map
API脚本的延迟加载。

因此,我四处搜索,找到了需要稍作调整的解决方案,但是我的问题是它只会加载一张地图,而不会加载其他地图。

我的HTML看起来像这样:

<div id="mapParis" class="google-map" lat="48.833" long="2.333"></div>
<div id="mapWashington" class="google-map" lat="38.917" long="-77.000"></div>
<div id="mapTokyo" class="google-map" lat="35.667" long="139.750"></div>

和指令:

// Google Map
app.directive('googleMap', ['$window', '$q', function( $window, $q ) {
    function loadScript() {
        console.log('loadScript');

        // use global document since Angular's $document is weak
        var s = document.createElement('script');
        s.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap';
        document.body.appendChild(s);
    }

    // Lazy loading of the script
    function lazyLoadApi(key) {
        console.log('lazyLoadApi');

        var deferred = $q.defer();

        $window.initMap = function () {
            deferred.resolve();
        };

        if ( $window.attachEvent ) {  
            $window.attachEvent('onload', loadScript); 
        } else {
            $window.addEventListener('load', loadScript, false);
        }

        return deferred.promise;
    }

    return {
        restrict: 'C', // restrict by class name
        scope: {
            mapId: '@id', // map ID
            lat: '@',     // latitude
            long: '@'     // longitude
        },
        link: function($scope, elem, attrs) {
            // Check if latitude and longitude are specified
            if ( angular.isDefined($scope.lat) && angular.isDefined($scope.long) ) {
                console.log('-----');

                // Initialize the map
                $scope.initialize = function() {
                    console.log($scope.mapId);

                    $scope.location = new google.maps.LatLng($scope.lat, $scope.long);

                    $scope.mapOptions = {
                        zoom: 6,
                        center: $scope.location
                    };

                    $scope.map = new google.maps.Map(document.getElementById($scope.mapId), $scope.mapOptions);

                    new google.maps.Marker({
                        position: $scope.location,
                        map: $scope.map,
                    });
                }

                // Check if google map API is ready to run
                if ( $window.google && $window.google.maps ) {
                    console.log('gmaps already loaded');

                    // Google map already loaded
                    $scope.initialize();
                } else {
                    lazyLoadApi().then(function () {
                        // Promised resolved
                        console.log('promise resolved');

                        if ( $window.google && $window.google.maps ) {
                            // Google map loaded
                            console.log('gmaps loaded');

                            $scope.initialize();
                        } else {
                            // Google map NOT loaded
                            console.log('gmaps not loaded');
                        }
                    }, function () {
                        // Promise rejected
                        console.log('promise rejected');
                    });
                }
            }
        }
    };

这是带有3个映射的jsFiddle,您将看到仅加载了最后一个:http :
//jsfiddle.net/5Pk8f/1/

我想我在范围或履行承诺的方式上做错了事,但目前我还没有足够的主意…

谢谢!(对不起我的英语 不好

作为更新,这里提供了我想到的完整解决方案:
http
://plnkr.co/edit/1NpquJ?p=preview(@maurycy plunker)

Google地图服务

// Lazy loading of Google Map API
app.service('loadGoogleMapAPI', ['$window', '$q', 
    function ( $window, $q ) {

        var deferred = $q.defer();

        // Load Google map API script
        function loadScript() {  
            // Use global document since Angular's $document is weak
            var script = document.createElement('script');
            script.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap';

            document.body.appendChild(script);
        }

        // Script loaded callback, send resolve
        $window.initMap = function () {
            deferred.resolve();
        }

        loadScript();

        return deferred.promise;
    }]);

Google Map指令

// Google Map
app.directive('googleMap', ['$rootScope', 'loadGoogleMapAPI', 
    function( $rootScope, loadGoogleMapAPI ) {

        return {
            restrict: 'C', // restrict by class name
            scope: {
                mapId: '@id', // map ID
                lat: '@',     // latitude
                long: '@'     // longitude
            },
            link: function( $scope, elem, attrs ) {

                // Check if latitude and longitude are specified
                if ( angular.isDefined($scope.lat) && angular.isDefined($scope.long) ) {

                    // Initialize the map
                    $scope.initialize = function() {                                        
                        $scope.location = new google.maps.LatLng($scope.lat, $scope.long);

                        $scope.mapOptions = {
                            zoom: 12,
                            center: $scope.location
                        };

                        $scope.map = new google.maps.Map(document.getElementById($scope.mapId), $scope.mapOptions);

                        new google.maps.Marker({
                            position: $scope.location,
                            map: $scope.map,
                        });
                    }

                    // Loads google map script
                    loadGoogleMapAPI.then(function () {
                        // Promised resolved
                        $scope.initialize();
                    }, function () {
                        // Promise rejected
                    });
                }
            }
        };
    }]);

HTML使用示例

<div id="mapParis" class="google-map" lat="48.833" long="2.333"></div>
<div id="mapWashington" class="google-map" lat="38.917" long="-77.000"></div>
<div id="mapTokyo" class="google-map" lat="35.667" long="139.750"></div>

再次感谢maurycy


问题答案:

您在此处遇到关于诺言和初始化的问题,我已经为您做得更干净了

显然jsfiddle已被删除,因此这里工作正常:http
://plnkr.co/edit/1NpquJ?p=preview

js

这是延迟加载gmap的服务

app.service('lazyLoadApi', function lazyLoadApi($window, $q) {
  function loadScript() {
    console.log('loadScript')
    // use global document since Angular's $document is weak
    var s = document.createElement('script')
    s.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap'
    document.body.appendChild(s)
  }
  var deferred = $q.defer()

  $window.initMap = function () {
    deferred.resolve()
  }

  if ($window.attachEvent) {
    $window.attachEvent('onload', loadScript)
  } else {
    $window.addEventListener('load', loadScript, false)
  }

  return deferred.promise
});

然后该指令执行应做的工作,仅与map一起使用,不将js文件加载到任何其他逻辑



 类似资料:
  • 问题内容: 我正在使用JQuery的几个插件,自定义窗口小部件和其他一些库。结果,我有几个.js和.css文件。我需要为网站创建一个加载器,因为加载需要一些时间。如果可以在导入所有内容之前显示加载程序,那就太好了: 我找到了一些教程,这些教程使我能够异步导入JavaScript库。例如,我可以做类似的事情: 由于某种原因,当我对所有文件执行相同操作时,页面将无法正常工作。我已经尝试了很长时间,试图

  • 问题内容: 我有一些特定于视图的脚本。但是,当angularjs加载视图时,该脚本似乎没有执行。 Index.html Main.html- 在ng-view下加载 在此示例中,当页面加载时,我看到网站上印有一个基本的hello世界。但是,我没有弹出任何消息说“你好,约翰”。 知道为什么我无法加载特定于某个视图的脚本吗? 额外信息 app.js 控制器/main.js 问题答案: 这就是 jqLi

  • 问题内容: 我已经使用安装了React 。它安装得很好,但是我试图将图像加载到我的一个组件(,文件路径:)中,但是没有加载。这是我的代码: 如果我在变量中写入图像路径,则会出现错误: 编译失败。 ./src/Components/common/Header.js中的错误 找不到模块:/ var / www / html / wistful / src / Components / common中的

  • 问题内容: 我正在使用http://angular-google-maps.org/,它是不错的Google角形地图库。但是我想使用这样的地图实例,它不是在angularjs上下文中加载的: 好的,我有mapInstance,我可以以编程方式使用它。但是在应用程序生命周期中,这种情况一直持续到很晚- 换句话说,我想在其他代码之前加载整个指令(并获取地图实例),而我只是不想使用其他地图事件。 问题答

  • 我从这个问题中编辑了一个柱塞

  • 问题内容: 我正在尝试构建一个指令,该 指令 负责在其声明的元素上 添加更多指令 。例如,我要建立一个指令,需要增加的照顾,和。 如果我尝试添加这些属性然后使用,则显然会生成一个无限循环,因此我正在检查是否已添加所需的属性: 当然,如果我没有该元素,则将设置属性,但不会引导该指令。 这种方法正确还是我做错了?有没有更好的方法来实现相同的行为? UDPATE :鉴于这是实现此目标的唯一方法,是否有一