在 AngularJS 应用程序中单击 Google 地图中的标记不会更新显示的数据

Posted

技术标签:

【中文标题】在 AngularJS 应用程序中单击 Google 地图中的标记不会更新显示的数据【英文标题】:Clicking on Marker in Google Maps in AngularJS app doesn't update data displayed 【发布时间】:2018-02-16 13:05:47 【问题描述】:

我在 AngularJS 中有一个非常简单的谷歌地图实现。它会显示一个搜索框,键入任何位置都会在下面的地图上添加一个标记。在该地图下方有一个简单的标签“位置:”,当我单击标记时我想更新它。绑定变量值已更新,但不会反映在页面上。这里有什么问题。这是 Plunker 上的完整代码。

Plunker

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Angular Google Maps</title>

    <!-- Styles -->
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" />
    <style type="text/css">
        h3 img 
            max-height: 50px;
        
        #map  
            height: 400px;
            margin: 20px 0;
            border-radius: 5px;
            border: 1px solid silver;
        
    </style>
</head>
<body>

<div class="container" ng-app="myApp" ng-controller="newPlaceCtrl">
    
    <h3 class="clearfix">
        <img class="pull-left" src="http://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/AngularJS_logo.svg/695px-AngularJS_logo.svg.png"/>
        <img class="pull-right" src="http://upload.wikimedia.org/wikipedia/commons/9/9a/Google_maps_logo.png"/>
    </h3>
    
    <div class="alert alert-danger text-center" role="alert" ng-show="apiError">
        <b>API Error : </b>
        <span> apiStatus </span>
    </div>
    
    <form name="searchForm" novalidate 
    ng-submit="search()">
        <div class="input-group">
            <input name="place" type="text" class="form-control" 
            ng-model="searchPlace" required autofocus />
            <span class="input-group-btn">
                <button class="btn btn-primary" 
                ng-disabled="searchForm.$invalid">Search</button>
            </span>
        </div>
    </form>
        
    <div id="map"></div>
    
    <div><strong>Position:</strong>  pos  </div>

    <form name="resForm" class="form-horizontal" novalidate 
    ng-submit="send()">
        <div class="form-group">
            <label for="resName" class="col-xs-2 control-label">Name</label>
            <div class="col-xs-10">
                <input name="resName" type="text" class="form-control" 
                ng-model="place.name" required />
            </div>
        </div>
        <div class="form-group">
            <label for="resLat" class="col-xs-2 control-label">Latitude</label>
            <div class="col-xs-10">
                <input name="resLat" type="number" class="form-control" 
                ng-model="place.lat" required />
            </div>
        </div>
        <div class="form-group">
            <label for="resLng" class="col-xs-2 control-label">Longitude</label>
            <div class="col-xs-10">
                <input name="resLng" type="number" class="form-control" 
                ng-model="place.lng" required />
            </div>
        </div>
        <div class="form-group">
            <div class="col-xs-offset-2 col-xs-10">
                <button class="btn btn-success" 
                ng-disabled="resForm.$invalid">Confirm</button>
            </div>
        </div>
    </form>
    
</div>

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<script src="//maps.googleapis.com/maps/api/js?key=AIzaSyC2CzzxH7VsJNWcKobDZzEKfZoyzp4QYkI&libraries=places"></script>
<script type="text/javascript">
    var app = angular.module('myApp', []);

app.service('Map', function($q) 
    
    this.init = function() 
        var options = 
            center: new google.maps.LatLng(40.7127837, -74.00594130000002),
            zoom: 13,
            disableDefaultUI: true    
        
        this.map = new google.maps.Map(
            document.getElementById("map"), options
        );
        this.places = new google.maps.places.PlacesService(this.map);
    
    
    this.search = function(str) 
        var d = $q.defer();
        this.places.textSearch(query: str, function(results, status) 
            if (status == 'OK') 
                d.resolve(results[0]);
            
            else d.reject(status);
        );
        return d.promise;
    
    
    this.addMarker = function(res) 
        if(this.marker) this.marker.setMap(null);
        this.marker = new google.maps.Marker(
            map: this.map,
            position: res.geometry.location,
            animation: google.maps.Animation.DROP
        );
        this.map.setCenter(res.geometry.location);
        return this.marker;
    
);

app.controller('newPlaceCtrl', function($scope, Map) 
    
    $scope.place = ;
    $scope.pos = 'a';
    
    $scope.search = function() 
        $scope.apiError = false;
        Map.search($scope.searchPlace)
        .then(
            function(res)  // success
                var marker = Map.addMarker(res);
                
                /****************************************************************/
                /* DOESNT WORK */
                /****************************************************************/
                marker.addListener('click', function(e) 
                    console.log($scope.pos);
                    $scope.pos = res.name;
                    console.log($scope.pos);    // *** varaible value is updated here but not displayed on page
                );

                /* NEITHER THIS */
                // google.maps.event.addListener(marker, 'click', function () 
                //     console.log($scope.pos);
                //     $scope.pos = res.name;
                //     console.log($scope.pos);
                // );

                /****************************************************************/

                $scope.place.name = res.name;
                $scope.place.lat = res.geometry.location.lat();
                $scope.place.lng = res.geometry.location.lng();
            ,
            function(status)  // error
                $scope.apiError = true;
                $scope.apiStatus = status;
            
        );
    
    
    $scope.send = function() 
        alert($scope.place.name + ' : ' + $scope.place.lat + ', ' + $scope.place.lng);    
    
    
    Map.init();
);

</script>

</body>
</html>

【问题讨论】:

【参考方案1】:

你非常接近。 首先,$scope.pos 应该是一个空字符串,所以删除 'a' 并更改为 $scope.pos = '';

接下来,像这样在你的监听器中添加一个$scope.$apply 函数

marker.addListener('click', function(e) 
    $scope.$apply(function()
        $scope.pos = res.name;
    );
);

【讨论】:

很高兴它成功了! $scope.$apply() “同步”你的 $scope。这个链接很好地解释了它:) ***.com/questions/29544263/…

以上是关于在 AngularJS 应用程序中单击 Google 地图中的标记不会更新显示的数据的主要内容,如果未能解决你的问题,请参考以下文章

在AngularJS中单击标记时无法导航到新屏幕

带有 mousedown 事件处理程序的 AngularJS 指令,但单击事件永远不会触发

单击“应用”按钮后应用 angularjs 过滤器

单击后在 AngularJS 中切换视图

创建一个可以在 angularjs 中单击的悬停工具提示

使用AngularJS单击添加按钮时如何在表中插入新数据行