1

I'm using the angular-google-maps directive. I'm using a ui-boostrap modal to display the map. I have my modal content defined in a file named mapSelectLocation.html. Here is how I open the modal:

var modalInstance = $modal.open({
    templateUrl: '/path/to/templates/mapSelectLocation.html',
    controller: 'mapSelectLocationController'
});

mapSelectLocation.html:

<div class='modal-body'>
    <ui-gmap-google-map ng-if="readyForMap" center='map.center' zoom='map.zoom'>         </ui-gmap-google-map>
</div>

mapSelectLocationController:

function mapSelectLocationController($scope, $modalInstance) {
    $scope.map = { center: { latitude: 39.8433, longitude: -105.1190 }, zoom: 10 };
    $scope.readyForMap = true;
}

This displays the popup and renders the map appropriately. However, when I close the modal and re-open it, the map does not render properly. Most of the map area is grayed out, with only a small portion of the map visible in the top-left corner.

However, if I move the content of mapSelectLocation.html from the file itself into an angular template script on the same page, it opens and reopens just fine, rendering correctly each time:

<script type="text/ng-template" id="mapSelectLocation.template">
    <div class='modal-body'>
        <ui-gmap-google-map ng-if="readyForMap" center='map.center' zoom='map.zoom'>         </ui-gmap-google-map>
    </div>
</script>

And of course update the templateUrl as well:

var modalInstance = $modal.open({
    templateUrl: 'mapSelectLocation.template',
    controller: 'mapSelectLocationController'
});

Can someone please tell me why it is not working to have my modal content in a separate file? I would rather keep it separate than have to use an angular script template.

spoof3r
  • 607
  • 8
  • 23
  • Try it either without `ng-if` or use `ng-show` instead – doog abides Mar 02 '15 at 04:55
  • Are you sure the location of your html template is same as that of your page? – Vaibhav Pingle Mar 02 '15 at 04:55
  • Do you have any plunkr/fiddle for this? – Vinay K Mar 02 '15 at 04:57
  • agree with @doogabides. ng-if is not the right thing to apply here. – Vaibhav Pingle Mar 02 '15 at 05:00
  • Apologies, I have updated the code for better clarification. As for the ng-if: the current solution I found (and posted above) using an angular template does not work unless I use the ng-if. Another SO answer mentioned ng-if should be used so that the content is not included into the DOM until it is ready, which will cause the map to render properly. I tried removing the ng-if just now after reading these comments, and sure enough it no longer renders the map. It seems ng-if is necessary. – spoof3r Mar 02 '15 at 05:03
  • Also, I just confirmed that omitting ng-if does not work when I reference the actual template file itself. Replacing with ng-show did not work either :-( – spoof3r Mar 02 '15 at 05:07

1 Answers1

2

Found a solution. Angular-Google-Maps provides the uiGmapIsReady service for letting you know when the ui-map is ready. Using this promise you can pass a callback function that allows you to access the map's control property which has a refresh() function available to it which will refresh the map. This allows the map to be refreshed, rendering it correctly on subsequent modal opens.

Here is an example solution:

var module = angular.module('test', ['ui.bootstrap', 'uiGmapgoogle-maps']);
module.controller('controllerA', ['$scope', '$modal', 'uiGmapIsReady', controllerA]);
module.controller('mapSelectLocationController', ['$scope', '$modalInstance', 'uiGmapIsReady', mapSelectLocationController]);

function controllerA($scope, $modal, uiGmapIsReady) {

    $scope.openMapDialog = function () {
        var modalInstance = $modal.open({
            templateUrl: '/app/mapTemplate.html',
            controller: 'mapSelectLocationController'
        });

        modalInstance.result.then(function (test) {
            debugger;
        });
    }
}

function mapSelectLocationController($scope, $modalInstance, uiGmapIsReady) {
    $scope.map = { center: { latitude: 39.8433, longitude: -105.1190 }, zoom: 10 };
    $scope.readyForMap = true;
    $scope.control = {};

    uiGmapIsReady.promise().then(function (maps) {
        $scope.control.refresh();
    });
}

module.config(function (uiGmapGoogleMapApiProvider) {
    uiGmapGoogleMapApiProvider.configure({
        v: '3.17',
        libraries: 'weather,geometry,visualization'
    });
});

And the template:

<div class="modal-body">
<h4>Click a location on the map</h4>
<hr />
<div class="row">
    <ui-gmap-google-map center='map.center' control='control' zoom='map.zoom'></ui-gmap-google-map>
</div>

<h4>Available Addresses</h4>
<hr />
<div class="row">
    <div class="grid no-border">
        <div class="grid-body">
            Addresses will be listed here...
        </div>
    </div>
</div>

For angular google maps v2 and below, see this SO answer: How to wait for Angular Google Maps to append getGMap to the control object Basically as of v2 use the uiGmapIsReady.

Community
  • 1
  • 1
spoof3r
  • 607
  • 8
  • 23