如果谷歌地图-api不可访问,如何让角度谷歌地图懒惰加载而不破坏页面?

时间:2014-09-04 16:00:41

标签: angularjs google-maps google-maps-api-3 requirejs

我使用requirejs + angularjs + angular-google-maps来显示地图上某个房子的位置。

在我的页面上,有一张地图和一些其他信息,其他信息比地图更重要,所以我希望地图可以懒得显示,即使它没关系,地图也没有显示由于某种原因(例如,无法加载谷歌地图api)。

我的代码是这样的:

main.js

require.config({
    baseUrl: 'app',
    paths: {
        jquery: '../bower_components/jquery/dist/jquery',
        angular: '../bower_components/angular/angular',
        'angular-google-maps': '../bower_components/angular-google-maps/dist/angular-google-maps',
        googlemaps: '../bower_components/googlemaps-amd/src/googlemaps',
        async: '../bower_components/requirejs-plugins/src/async',
        underscore: '../bower_components/underscore/underscore'
    },
    shim: {
        angular: {
            exports: "angular"
        },
        'angular-google-maps': {
            deps: ['googlemaps!', 'angular', 'underscore']
        }
    }
});

require(['googlemaps!', 'jquery', 'angular', 'angular-google-maps', 'controllers'],
    function (googlemaps, jquery, angular, angularGoogleMaps, controllers) {
        angular.module('app', ['controllers', 'google-maps']);

        angular.element(document).ready(function () {
            angular.bootstrap(document, ['app']);
        });
    }
);

我使用了googlemaps-amd库这是一个requirejs模块,并将异步加载google-maps-api-v3,并将等到api加载成功。

angular-google-maps模块提供名为google-maps的angularjs模块,我的主角度模块app依赖于它。

因此在代码中,当google-maps-api-v3和angular-google-maps全部加载时,我的angularjs代码将被执行。这是我在这个问题上最关心的问题。

controllers.js的内容:

controllers.js

define(['angular'], function (angular) {
    return angular.module('controllers', [])
        .controller('Ctrl', ['$scope', function ($scope) {
            $scope.hello = "Hello, world";
            $scope.houses = [
                {
                    key: '111',
                    location: {
                        "longitude": 144.99918,
                        "latitude": -37.81859
                    }
                },
                {
                    key: '222',
                    location: {
                        "longitude": 140.99918,
                        "latitude": -40.81859
                    }
                }
            ];

            $scope.map = {
                center: {
                    "longitude": 144.99918,
                    "latitude": -37.81859
                },
                zoom: 13,
                options: {
                    disableDefaultUI: !0,
                    mapTypeControl: !1,
                    tilt: 45
                }
            }
        }])
});

它只是定义了一个控制器和map所需的数据。

和html:

的index.html

<html>
<head>
    <link type="text/css" rel="stylesheet" href="css/main.css">
</head>
<body>
hello
<div ng-controller="Ctrl">
    {{hello}}
    <div ng-if="map">
        <google-map center="map.center" zoom="map.zoom" options="map.options">
            <markers
                    models="houses"
                    idKey="'key'"
                    doRebuildAll="true"
                    doCluster="true"
                    fit="true"
                    coords="'location'">
            </markers>
        </google-map>
    </div>
    {{houses}}
</div>
</body>
<script type="text/javascript" data-main="../build/main" src="../bower_components/requirejs/require.js"></script>
</html>

../build/main打包并缩小了一个js文件,但您可以认为它是我在开头提供的main.js

现在地图可以正确显示,但是你知道,出于某种原因,google-map-api在某些国家/地区被阻止或极其缓慢是很常见的。然后页面完全被破坏了,你将显示占位符{{hello}}{{houses}},即使它们在地图上不是很相关。遗憾的是。

是否可以让angular-google-maps指令懒惰加载?

即使它非常缓慢或破裂,也不会阻止其他内容?

2 个答案:

答案 0 :(得分:0)

好吧,代替使用{{variableName}},您可以使用括号不显示...来解决该问题。

否则,您只需添加一些try ... catch语句以确保页面不会中断

答案 1 :(得分:0)

在玩谷歌地图的小方面项目中,在绘制地图之前,我遇到了数据准备就绪的问题。 我在地图'tilesloaded'事件中解析的承诺中操纵了地图。 类似的东西应该适合你,虽然我没有使用angular-google-maps ...

.directive('aMap', function() {
    var mapid = 1;
    return {
        restrict: 'E',
        link: function (scope, element, attrs, ctrl) {
            var el = document.createElement("div");
            el.style.width = "100%";
            el.style.height = "100%";
            element.prepend(el);
            var mapOptions = {
                    center: new google.maps.LatLng(0,0),
                    zoom  : 1
            };
            var map = new google.maps.Map(el, mapOptions);
            map.id = mapid++;
            google.maps.event.addListener(map, 'tilesloaded', function () {
                google.maps.event.clearListeners(map, 'tilesloaded');
                if ( scope.mapDefer )
                    scope.mapDefer.resolve(map);
                return;
            });
        }
    };
})
.controller('myCtrl', function ($log, $scope, $q, StudyData, mngGeocodeService) {
    $scope.mapDefer = $q.defer();
    $scope.mapDefer.promise
    .then( function ( map ) { drawMap(map) } );

    function drawMap ( map ) {

        mngGeocodeService.get('United States of America')
        .then (
                function ( results, status ) {
                    if ( results.length === 0 )
                        return;
                    var bounds = new google.maps.LatLngBounds(
                            new google.maps.LatLng(results[0].geometry.viewport.southwest.lat, results[0].geometry.viewport.southwest.lng ),
                            new google.maps.LatLng(results[0].geometry.viewport.northeast.lat, results[0].geometry.viewport.northeast.lng )
                    );
                    map.fitBounds(bounds);
                }
        );

        for ( var i=0; i<StudyData.length; i++ ) {
            addCircle(map, i);
        }
    }
    function addCircle ( map, index ) {
        mngGeocodeService.get(StudyData[index].name)
        .then (
                function ( results, status ) {
                    if ( results.length === 0 )
                        return;
                    var radius = 30000 * Math.sqrt(100/StudyData[index].yearsBetweenAccidents);
                    new google.maps.Circle({
                        strokeColor: '#FF0000',
                        strokeOpacity: 0.8,
                        strokeWeight: 2,
                        fillColor: '#FF0000',
                        fillOpacity: 0.35,
                        map: map,
                        center: results[0].geometry.location,
                        radius: radius
                    });

                }
        );
    }

    return;
})