javascript - 更新 AngularJS 服务中的 $scope 对象不会更新 View

标签 javascript angularjs google-maps cordova ionic-framework

我正在尝试在 Angular/IonicFramework 中实现 Google map 。我正在使用指令、服务和 Controller 。我在 $scope 中有一个 map 、标记和地理定位对象。 View 中的 map 对象和标记对象会从服务更新,但地理定位对象不会。

模板/ View :

<div class="item item-input item-stacked-label item-icon-right">
  <div>
    Location
    <a ng-click="centerOnMe()">
      <i class="icon ion-android-locate" style="font-size:24px"></i>
    </a>
  </div>
  <textarea style="margin-top: 0px; margin-bottom: 0px; height: 45px;" placeholder="Location not found." disabled>{{geoloc.addr}}</textarea>
</div>
<div class="item item-input">
  <div class="input-label">Map</div>
</div>
<div class="item item-input" style="height:15em;">
  <ion-content scroll="false">
    <map on-create="mapCreated(map, geoloc, marker)"></map>
  </ion-content>
</div>

map 指令:

angular.module('starter.directives', [])

.directive('map', function(MapService) {
  return {
    restrict: 'E',
    scope: {
      onCreate: '&'
    },
    link: function ($scope, $element, $attr) {
      function initialize() {
        var mapOptions = {
          center: new google.maps.LatLng(43.07493, -89.381388),
          zoom: 16,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        var map = new google.maps.Map($element[0], mapOptions);
        var geoloc = {
          lat: null, lng: null, str: null, brgy: null,
          muni: null, reg: null, addr: null
        };
        var marker = new google.maps.Marker({
          map: map
        });

        $scope.onCreate(
          {
            map: map,         //link map to map in controller
            geoloc: geoloc,   //link geoloc to geoloc in controller
            marker: marker    //link marker to marker in controller
          });

        // Stop the side bar from dragging when mousedown/tapdown on the map
        google.maps.event.addDomListener($element[0], 'mousedown', function (e) {
          e.preventDefault();
          return false;
        });
      }

      if (document.readyState === "complete") {
        initialize();
      } else {
        google.maps.event.addDomListener(window, 'load', initialize);
      }
    }
  }
});

map Controller :

angular.module('starter.controllers', [])

.controller('MapCtrl', function($scope, $ionicLoading, MapService) {
  $scope.mapCreated = function(map, geoloc, marker) {
    $scope.map = map;       //sets the map from the directive to the $scope
    $scope.geoloc = geoloc; //sets the geoloc from the directive to the $scope
    $scope.marker = marker; //sets the marker from the directive to the $scope
  };

  $scope.centerOnMe = function () {
    console.log('Centering..');
    if (!$scope.map && !$scope.marker && !$scope.geoloc) {
      return;
    }
    $scope.loading = $ionicLoading.show({
      template: 'Getting current location...',
      noBackdrop: true
    });

    $scope.geoloc = MapService.getCurrentLocation($ionicLoading, $scope.map, $scope.geoloc, $scope.marker);
    // ^^^ This doesn't seem to work. $scope.geoloc doesn't get updated immediately, while $scope.map and $scope.marker gets updated immediately. Has to be invoked twice for $scope.geoloc to be updated.
  }
});

map 服务:

angular.module('starter.services', [])

.factory('MapService', function() {
  return {
    getCurrentLocation: function($ionicLoading, map, geoloc, marker) {
      navigator.geolocation.getCurrentPosition(function (pos) { //callback if get location succeeds

          geoloc.lat = pos.coords.latitude;
          geoloc.lng = pos.coords.longitude;

          var latlngpos = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
          var geocoder = new google.maps.Geocoder();

          geocoder.geocode({'latLng': latlngpos}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
              if (results[0]) {
                map.setZoom(16);
                marker.setOptions({
                    position: latlngpos,
                    map: map
                });

                geoloc.str = results[0].address_components[0].short_name; //type:route
                geoloc.brgy = results[0].address_components[1].short_name; //type:neighborhood
                geoloc.muni = results[0].address_components[2].short_name; //type:locatlity
                geoloc.reg = results[0].address_components[3].short_name; //type:admnistrative_area_level_1

                geoloc.addr = results[0].formatted_address;

              } else {
                console.log('No results found');
              }
            } else {
              console.log('Geocoder failed due to: ' + status);
            }
          });

          map.setCenter(latlngpos);
          $ionicLoading.hide();
      }, function (error) { //callback if get location fails
        alert('Unable to get location: ' + error.message);
      });

      return geoloc;
    }
  } 
})
;

我的实现基于这里:

http://www.jeffvandalsum.com/integrating-google-maps-api-with-angular/

我已经按照此处建议的解决方案进行操作,但是 $scope.geoloc 对象仍然没有更新:

Angular directive scope between google maps and a controller

Phonegap not firing GoogleMaps v3 domListener function inside Angularjs directive

最佳答案

尝试换行

$scope.geoloc = MapService.getCurrentLocation($ionicLoading,$scope.map, $scope.geoloc, $scope.marker);

使用 $timeout

angular.module('starter.controllers', [])

.controller('MapCtrl', function($scope,$timeout, $ionicLoading, MapService) {
    $scope.mapCreated = function(map, geoloc, marker) {
    $scope.map = map;       //sets the map from the directive to the $scope
    $scope.geoloc = geoloc; //sets the geoloc from the directive to the $scope
    $scope.marker = marker; //sets the marker from the directive to the $scope
  };

  $scope.centerOnMe = function () {
     console.log('Centering..');
     if (!$scope.map && !$scope.marker && !$scope.geoloc) {
       return;
     }
     $scope.loading = $ionicLoading.show({
       template: 'Getting current location...',
       noBackdrop: true
     });
    $timeout(function(){
         $scope.geoloc = MapService.getCurrentLocation($ionicLoading, $scope.map, $scope.geoloc, $scope.marker);
         // ^^^ This doesn't seem to work. $scope.geoloc doesn't get updated immediately, while $scope.map and $scope.marker gets updated immediately. Has to be invoked twice for $scope.geoloc to be updated.
    });
  }
});

旁注:这不一定是最佳方式,但它应该会触发您的 $scope.geoloc 正确更新。

我还建议 Gajotres's tutorial .

希望这对您有所帮助!

关于javascript - 更新 AngularJS 服务中的 $scope 对象不会更新 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30980487/

相关文章:

javascript - 使用 map() 返回数组时 Uncaught Error

javascript - 不是常见范围的函数错误

javascript - AngularJS指令对象有 "No Method"

android - 我将如何制作谷歌网络 map 安卓原生 map ?

javascript - 创建自定义 URL 以触发按钮

javascript - 使用 JavaScript onClick 关闭窗口

javascript - ng-model 未更新日期时间字段已更改

database - 在 gps 跟踪中将地址保存到数据库

java - 计算手机实际行驶距离

javascript - Express 端点对于 POST 返回 404,对于 GET 返回 200