javascript - 动态添加时,第二个 Google map 无法正确呈现

标签 javascript html angularjs google-maps angular-ui-bootstrap

以下 HTML,当复制到 .html 文件并在浏览器中查看时,直接显示了我的问题。

<!DOCTYPE HTML>
<html ng-app="myApp">

<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.min.js"> </script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"> </script>

<script>

    var mapOptions = {
        zoom: 5,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
    };

    var myApp = angular.module('myApp', ['ui.bootstrap']);

    var myController = function($scope){
        $scope.locations = [];

        $scope.addLocation = function(){
            var id = $scope.locations.length+1;

            $scope.locations.push({ id: id, city: $scope.newLocation.city, country: $scope.newLocation.country });

            $scope.newLocation = { city:'', country:'' };
        }

        $scope.$watch('locations', function(){

            for(var i = 0; i < $scope.locations.length; i++){
                var thisLocation = $scope.locations[i];

                if(!thisLocation.rendered){
                    var geocoder = new google.maps.Geocoder();

                    var id = thisLocation.id;
                    var address = thisLocation.city + ' ' + thisLocation.country;

                    geocoder.geocode({ 'address': address }, function (results, status) {
                        if (status == google.maps.GeocoderStatus.OK) {
                            var longitude = results[0].geometry.location.A;
                            var latitude = results[0].geometry.location.k;

                            var map = $scope.displayMap(latitude, longitude, 'Test' + id, id);
                            google.maps.event.trigger(map, "resize");
                        }
                    });

                    thisLocation.rendered = true;
                }


            }

        }, true);

        $scope.displayMap = function displayMap(latitude, longitude, name, id) {

            var mapDiv = document.getElementById('map' + id);
            if (mapDiv) mapDiv.style.display = "block";

            var mapCanvas = document.getElementById('map-canvas' + id);
            if (mapCanvas) mapCanvas.style.height = "400px";

            var map = new google.maps.Map(document.getElementById('map-canvas' + id), mapOptions);

            var locCoords = new google.maps.LatLng(latitude, longitude);

            map.setCenter(locCoords);

            new google.maps.Marker({
                position: locCoords,
                map: map,
                title: name
            });

            return map;
        }

        $scope.newLocation = { city:'', country:'' };
    }

    myController.$inject = ['$scope'];
    myApp.controller('myController', myController);
</script>

</head>

<body ng-controller="myController">

<form ng-submit="addLocation()">
    <label for="city"><input id="city" ng-model="newLocation.city" required /></label>
    <label for="country"><input id="country" ng-model="newLocation.country" required /></label>
    <input type="submit" value="Submit" />
</form>

<tabset>
    <tab ng-repeat="location in locations" heading="{{location.city}}">
        <div id="map{{location.id}}" class="map">
            <div id="map-canvas{{location.id}}" class="map-canvas">
                Map goes here
            </div>
        </div>
    </tab>
</tabset>

</body>

</html>

基本上,您只需填写一次表单即可将 map 添加到选项卡集中,并且效果很好:

First map looking fine

再次填写表格以添加第二张 map ,这是一场灾难:

Second map, disaster zone

Chrome 的开发者控制台中没有任何内容表明存在问题。

我无法确定这是 Google map 问题、Angular 问题还是 Angular 引导指令问题,所以我使用这三个问题创建了这个模型,并尽可能地模仿我的实际代码。

任何人都可以阐明这里发生的事情吗?

谢谢

最佳答案

好吧,事实证明 Google map 无法处理非事件选项卡上的渲染,因此我需要创建选项卡并将其设置为事件状态,然后再渲染 map 。

我改变了:

$scope.locations.push({ id: id, city: $scope.newLocation.city, country: $scope.newLocation.country });

收件人:

$scope.locations.push({ id: id, city: $scope.newLocation.city, country: $scope.newLocation.country, active: true });

将以下内容添加到我的 for 循环的末尾:

thisLocation.active = true;

Angular 似乎足够聪明,可以在您将此设置为 true 时将其他选项卡的事件属性设置为 false。

最后,我将选项卡元素的事件属性设置为模型的事件属性:

<tab ng-repeat="location in locations" heading="{{location.city}}" active="location.active" >

下面是一个工作示例:

<!DOCTYPE HTML>
<html ng-app="myApp">

<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.min.js"> </script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"> </script>

<script>

    var mapOptions = {
        zoom: 5,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
    };

    var myApp = angular.module('myApp', ['ui.bootstrap']);

    var myController = function($scope){
        $scope.locations = [];

        $scope.addLocation = function(){
            var id = $scope.locations.length+1;

            $scope.locations.push({ id: id, city: $scope.newLocation.city, country: $scope.newLocation.country, active: true });

            $scope.newLocation = { city:'', country:'' };
        }

        $scope.$watch('locations', function(){

            for(var i = 0; i < $scope.locations.length; i++){
                var thisLocation = $scope.locations[i];

                if(!thisLocation.rendered){ 

                    var geocoder = new google.maps.Geocoder();

                    var id = thisLocation.id;
                    var address = thisLocation.city + ' ' + thisLocation.country;

                    geocoder.geocode({ 'address': address }, function (results, status) {
                        if (status == google.maps.GeocoderStatus.OK) {
                            var longitude = results[0].geometry.location.A;
                            var latitude = results[0].geometry.location.k;

                            var map = $scope.displayMap(latitude, longitude, 'Test' + id, id);
                            google.maps.event.trigger(map, "resize");
                        }
                    });

                    thisLocation.active = true;
                    thisLocation.rendered = true;
                }


            }

        }, true);

        $scope.displayMap = function displayMap(latitude, longitude, name, id) {

            var mapDiv = document.getElementById('map' + id);
            if (mapDiv) mapDiv.style.display = "block";

            var mapCanvas = document.getElementById('map-canvas' + id);
            if (mapCanvas) mapCanvas.style.height = "400px";

            var map = new google.maps.Map(document.getElementById('map-canvas' + id), mapOptions);

            var locCoords = new google.maps.LatLng(latitude, longitude);

            map.setCenter(locCoords);

            new google.maps.Marker({
                position: locCoords,
                map: map,
                title: name
            });

            google.maps.event.trigger(map, "resize");

            return map;
        }

        $scope.newLocation = { city:'', country:'' };
    }

    myController.$inject = ['$scope'];
    myApp.controller('myController', myController);
</script>

</head>

<body ng-controller="myController">

<form ng-submit="addLocation()">
    <label for="city"><input id="city" ng-model="newLocation.city" required /></label>
    <label for="country"><input id="country" ng-model="newLocation.country" required /></label>
    <input type="submit" value="Submit" />
</form>

<tabset>
    <tab ng-repeat="location in locations" heading="{{location.city}}" active="location.active" >
        <div id="map{{location.id}}" class="map">
            <div id="map-canvas{{location.id}}" class="map-canvas">
                Map goes here
            </div>
        </div>
    </tab>
</tabset>

</body>

</html>

关于javascript - 动态添加时,第二个 Google map 无法正确呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23957167/

相关文章:

javascript - 需要在页面加载后立即调用一个函数

javascript - 客户端和服务器的时间不一样,为什么?

java - HTTP 状态 415 – 使用 Angular js 的 Spring MVC 中出现不支持的媒体类型错误

javascript - 如何禁用 AngularJS 多选?

javascript - Mediarecorder : How to support audio recording on Safari, IE 11?

php - 在 .then() 函数内尝试 angular.forEach 时出错

javascript - JS获取对象坐标

javascript - 检查元素是否具有 CSS 类。如果没有添加的话

html - 如何通过CSS放置 flex 的文字

javascript - 在Javascript中,如何从下拉列表和表单中总结数组中的所有值?