Google Maps in modal not showed after two times op

2019-02-26 02:24发布

问题:

I'm created a Google Map in a modal view, once I'm open that modal, the map was showed. Then, I clicked nav-back-button to go to main page. After that I tried to open the modal to view the map again, but the map didn't showed.

Demo here: http://codepen.io/aishahismail/pen/vLZprV

HTML:

   <script id="modal.html" type="text/ng-template">
      <div class="modal">
        <header class="bar bar-header bar-positive">
          <h1 class="title">I'm A Modal</h1>
          <div class="button button-clear" ng-click="modal.hide()"><span class="icon ion-close"></span></div>
        </header>
        <content has-header="true" padding="true">
          <p>This is a map</p>
          <div id="map" data-tap-disabled="true"></div>
        </content>
      </div>
    </script>

Javascript: Controller

.controller('HomeTabCtrl', function($scope, $ionicModal, $ionicLoading, $compile) {
  console.log('HomeTabCtrl');

    $ionicModal.fromTemplateUrl('modal.html', function($ionicModal) {
        $scope.modal = $ionicModal;
    }, {
        scope: $scope,
        animation: 'slide-in-up'
    });  

  $scope.showMap = function (){
        var myLatlng = new google.maps.LatLng(43.07493,-89.381388);

        var mapOptions = {
          center: myLatlng,
          zoom: 16,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("map"),
            mapOptions);

        //Marker + infowindow + angularjs compiled ng-click
        var contentString = "<div><a ng-click='clickTest()'>Click me!</a></div>";
        var compiled = $compile(contentString)($scope);

        var infowindow = new google.maps.InfoWindow({
          content: compiled[0]
        });

        var marker = new google.maps.Marker({
          position: myLatlng,
          map: map,
          title: 'Uluru (Ayers Rock)'
        });

        google.maps.event.addListener(marker, 'click', function() {
          infowindow.open(map,marker);
        });

        $scope.map = map;
  }

  $scope.openModal = function(){
    $scope.modal.show();
    $scope.showMap();
  }
});

I found the same question in stack overflow Google maps in modal only displays first map but still didn't got the answer. I've been looking it in 1 day, but I'm still cannot solve this problem. I hope somebody can help me.

回答1:

Moving the code to a mainCtrl instead of HomeTabCtrl resolve the issue:

check this CodePen

HTML:

<body ng-controller="mainCtrl">
...

JS:

.controller('mainCtrl', function($scope, $ionicModal, $compile) {
// the code previously in HomeTabCtrl
}

I noticed that you are using an old version of Ionic and also old-style directives. Here is a version updated of Ionic app using Angular-google-maps:

http://plnkr.co/edit/n4Qr3OMcGIb5uU28xISU?p=preview



回答2:

After almost 1 week sitting try to find the solution, finally I've got the answer.

All the code is same stated in the questions, but I'm only add this in my controller. Check it out

//Remove modal
$scope.$on('$destroy', function () {
    $scope.modal.remove();
});

//Set $scope.map to null
$scope.$on('modal.hidden', function () {
    $scope.$on('$destroy', function () {
        $scope.map = null;
    });
});

I'm also change the maps module code, I'm used $cordovaGeolocation. Below is full code for homeTabCtrl

Javascript: homeTabCtrl

 .controller('HomeTabCtrl', function($scope, $ionicModal, $cordovaGeolocation) {

    $ionicModal.fromTemplateUrl('modal.html', function($ionicModal) {
        $scope.modal = $ionicModal;
    }, {
        scope: $scope,
        animation: 'slide-in-up'
    });  

     $scope.showMap = function (){
        var options = {
           timeout: 10000,
           enableHighAccuracy: true
        };

        $cordovaGeolocation.getCurrentPosition(options).then(function (position) {

          var latLng = new google.maps.LatLng(lat, lng);

          var mapOptions = {
             center: latLng,
             zoom: 15,
             mapTypeId: google.maps.MapTypeId.ROADMAP
          };

          $scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);

          google.maps.event.addListenerOnce($scope.map, 'idle', function () {

            var marker = new google.maps.Marker({
                map: $scope.map,
                animation: google.maps.Animation.DROP,
                position: latLng
            });
        });

        }, function (error) {
           alert("Could not get location");
        });
    };

    $scope.openModal = function(){
      $scope.modal.show();
      $scope.showMap();
    };

    //Remove modal
    $scope.$on('$destroy', function () {
        $scope.modal.remove();
    });

    //Set $scope.map to null
    $scope.$on('modal.hidden', function () {
        $scope.$on('$destroy', function () {
            $scope.map = null;
        });
    });
});