Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS服务中$scope对象的更新不更新视图_Javascript_Angularjs_Google Maps_Cordova_Ionic Framework - Fatal编程技术网

Javascript AngularJS服务中$scope对象的更新不更新视图

Javascript AngularJS服务中$scope对象的更新不更新视图,javascript,angularjs,google-maps,cordova,ionic-framework,Javascript,Angularjs,Google Maps,Cordova,Ionic Framework,我正在尝试在Angular/IonicFramework中实现Google地图。我使用的是指令、服务和控制器。我在$scope中有一个地图、标记和地理位置对象。视图中的地图对象和标记对象会从服务更新,而地理位置对象不会 模板/视图: <div class="item item-input item-stacked-label item-icon-right"> <div> Location <a ng-click="centerOnMe()"&g

我正在尝试在Angular/IonicFramework中实现Google地图。我使用的是指令、服务和控制器。我在
$scope
中有一个地图、标记和地理位置对象。视图中的地图对象和标记对象会从服务更新,而地理位置对象不会

模板/视图:

<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>
地图控制器:

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.
  }
});
.controller('MapCtrl', ["$scope", "$ionicLoading", "MapService", function($scope, $ionicLoading, MapService) {
  $scope.mapCreated = function(map, marker, geoloc) {
    $scope.map = map;       //sets the map from the directive to the $scope
    $scope.marker = marker; //sets the marker from the directive to the $scope
    $scope.geoloc = geoloc; //sets the geoloc from the directive to the $scope
    console.log('$scope.geoloc in $scope.mapCreated', $scope.geoloc);


    $scope.centerOnMe();
  };

  $scope.centerOnMe = function () {
    console.log("Centering");
    if (!$scope.geoloc && !$scope.map && !$scope.marker) {
      console.log($scope.map);
      console.log($scope.marker);
      console.log($scope.geoloc);

      return;
    }
    $scope.loading = $ionicLoading.show({
      template: 'Getting current location...',
      noBackdrop: true
    });

    MapService.getCurrLoc($ionicLoading);

  }
}])
地图服务:

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;
    }
  } 
})
;
.factory('MapService', function() {
  var service = {};
  service.map = null;
  service.marker = null;
  service.geoloc = {
      lat: 0.0,
      lng: 0.0,
      str: "",
      brgy: "",
      muni: "",
      reg: "",
      addr: ""  
  };

  service.init = function(map, marker) {
    this.map = map;
    this.marker = marker;
  }

  service.getCurrLoc = function($ionicLoading) {

    navigator.geolocation.getCurrentPosition(function (pos) { //callback if get location succeeds
      service.geoloc.lat = pos.coords.latitude;
      service.geoloc.lng = pos.coords.longitude;

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

      service.marker = new google.maps.Marker({
        position: latlngpos,
        map: service.map
      });

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

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


            service.map.setCenter(latlngpos);
            $ionicLoading.hide(); //hide loading prompt
          } else {
            console.log('No results found');
          }
        } else {
          console.log('Geocoder failed due to: ' + status);
        }
      });                     
    },
    function (error) { //callback if get location fails
    },
    { enableHighAccuracy: true }); //geolocation options
  }
  return service;
})
我的实现基于以下内容:

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

尝试包装

$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
正确更新

我还建议


希望这有帮助

我刚刚重写了指令、服务和控制器,现在它开始工作了。数据现在包含在服务中。然后我将服务注入指令和控制器

地图服务:

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;
    }
  } 
})
;
.factory('MapService', function() {
  var service = {};
  service.map = null;
  service.marker = null;
  service.geoloc = {
      lat: 0.0,
      lng: 0.0,
      str: "",
      brgy: "",
      muni: "",
      reg: "",
      addr: ""  
  };

  service.init = function(map, marker) {
    this.map = map;
    this.marker = marker;
  }

  service.getCurrLoc = function($ionicLoading) {

    navigator.geolocation.getCurrentPosition(function (pos) { //callback if get location succeeds
      service.geoloc.lat = pos.coords.latitude;
      service.geoloc.lng = pos.coords.longitude;

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

      service.marker = new google.maps.Marker({
        position: latlngpos,
        map: service.map
      });

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

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


            service.map.setCenter(latlngpos);
            $ionicLoading.hide(); //hide loading prompt
          } else {
            console.log('No results found');
          }
        } else {
          console.log('Geocoder failed due to: ' + status);
        }
      });                     
    },
    function (error) { //callback if get location fails
    },
    { enableHighAccuracy: true }); //geolocation options
  }
  return service;
})
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);
      }
    }
  }
});
.directive('map', ["MapService", function(MapService) {
  return {
    restrict: 'E',
    scope: {
      onCreate: '&'
    },
    link: function ($scope, $element, $attr) {
      function initialize() {
        var mapOptions = {
          //set to Philippines
          center: new google.maps.LatLng(14.6839606, 121.0622039),
          zoom: 16,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        MapService.map = new google.maps.Map($element[0], mapOptions);

        MapService.marker = new google.maps.Marker({
          map: MapService.map
        });

        $scope.onCreate(
          {
            map: MapService.map,         //link map to map in controller
            marker: MapService.marker,   //link marker to marker in controller
            geoloc: MapService.geoloc    //link geoloc to geoloc 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);
      }
    }
  }
}])
地图控制器:

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.
  }
});
.controller('MapCtrl', ["$scope", "$ionicLoading", "MapService", function($scope, $ionicLoading, MapService) {
  $scope.mapCreated = function(map, marker, geoloc) {
    $scope.map = map;       //sets the map from the directive to the $scope
    $scope.marker = marker; //sets the marker from the directive to the $scope
    $scope.geoloc = geoloc; //sets the geoloc from the directive to the $scope
    console.log('$scope.geoloc in $scope.mapCreated', $scope.geoloc);


    $scope.centerOnMe();
  };

  $scope.centerOnMe = function () {
    console.log("Centering");
    if (!$scope.geoloc && !$scope.map && !$scope.marker) {
      console.log($scope.map);
      console.log($scope.marker);
      console.log($scope.geoloc);

      return;
    }
    $scope.loading = $ionicLoading.show({
      template: 'Getting current location...',
      noBackdrop: true
    });

    MapService.getCurrLoc($ionicLoading);

  }
}])

getCurrentLocation($ionicLoading,$scope.map,$scope.geoloc,$scope.marker)。然后(函数(响应){$scope.geoloc=response.data;})@nikhil我得到了这个错误:
TypeError:MapService.getCurrentLocation(…)。那么它不是一个函数。让我再检查一下。“我可能错过了一些东西。”米斯卡布拉尔-请忽略我的回答。它不适合这里。