سؤال

I'm trying to toggle ng-show on a <section> that's adjacent to to a Google Map <div> by clicking a marker on the map. Essentially I want the click on the marker to behave like ng-click="toggle()".

When I click the marker, the true/false value logs correctly to the console, but ng-showdoesn't seem to be picking it up.

.controller('MapController', ['$scope',
    function($scope) {
      // $scope.visible = true;

      $scope.toggle = function(){
        console.log("Value before clicking: "+$scope.visible);
        $scope.visible = !$scope.visible;
        console.log("Value after clicking: "+$scope.visible);
      }

      $scope.buildMap = function(){
        var mapStyle=[
         // Map styles
        ];

      var myLatLng = new google.maps.LatLng(40.748453,-73.995548);

      var mapOptions = {
        // Map options
      };

      var myMap = new google.maps.StyledMapType(mapStyle,{name: "My Map"});

      var map = new google.maps.Map(document.getElementById('canvas'),mapOptions);
      map.mapTypes.set('myMapStyled', myMap);
      map.setMapTypeId('myMapStyled');

      var myMarker = new google.maps.Marker({
        map: map, position: myLatLng, title: "I’m Here"
      });

      google.maps.event.addListener(myMarker, 'click', function(e){
        $scope.toggle();
      });
    };
  }
])

Here it is on Plunker: http://plnkr.co/edit/z2UCTvqqWh04ZElu6npg?p=preview

Is this something to do with Angular, or is it something to do with the Maps API events?

Also, is it unwise to load the Maps API by shoving the whole thing inside a controller?

هل كانت مفيدة؟

المحلول

The event handler function in the following code lives "outside of Angular's world", which means the $digest loop will not be triggered and changes till not be reflected in the DOM:

google.maps.event.addListener(myMarker, 'click', function(e){
 $scope.toggle();
});

You need to use $apply:

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). Because we are calling into the angular framework we need to perform proper scope life cycle of exception handling, executing watches.

Example:

google.maps.event.addListener(myMarker, 'click', function(e){
  $scope.$apply(function () {
    $scope.toggle();
  });
});

Demo: http://plnkr.co/edit/cB2K31mSR7VmIAvC72WM?p=preview

نصائح أخرى

your toggle method should be wrapped in $scope.$apply so angular will be aware of changes and will update interface. So your toggle method will look like this

$scope.toggle = function(){
  $scope.$apply(function() {
    console.log("Before clicking toggle: "+$scope.visible);
    $scope.visible = !$scope.visible;
    console.log("After clicking toggle: "+$scope.visible);
  });
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top