2

I'm using Angular Google Maps with bootstrap3 and html5. I'm using angular google maps inside accordion.

The problem is that when I write Angular Google Maps inside accordion it showed as blank first time but when I come back to this page (state)by browse another page (state) then I works as normal. If I don't use accordion then it works fine always.

Here is code the accordion that show blank first time.

<accordion close-others="true">
    <accordion-group heading="Karta" is-open="map.open">
        <div class="panel-body">
            <div class="col-sm-12 col-xs-10 angular-google-map-container">                                 

                 <ui-gmap-google-map center="localMap.center" zoom="localMap.zoom" events="localMap.events" draggable="true" refresh="localMap.refreshMap" ng-class="{'crosshair': waitingForInput}">
                     <ui-gmap-markers idKey="id" models="localMap.markers" coords="'self'" fit="'true'" options="'options'">        
                     </ui-gmap-markers>
                 </ui-gmap-google-map>

            </div>
        </div>
    </accordion-group>
</accordion>

And if remove accordion then it works all time.

<div class="panel-body">
    <div class="col-sm-12 col-xs-10 angular-google-map-container">                                 

         <ui-gmap-google-map center="localMap.center" zoom="localMap.zoom" events="localMap.events" draggable="true" refresh="localMap.refreshMap" ng-class="{'crosshair': waitingForInput}">
             <ui-gmap-markers idKey="id" models="localMap.markers" coords="'self'" fit="'true'" options="'options'">        
             </ui-gmap-markers>
         </ui-gmap-google-map>

    </div>
</div>

enter image description here

Please help me to solve this issue.

Mohit Kanwar
  • 2,962
  • 7
  • 39
  • 59
Aamir Faried
  • 323
  • 3
  • 11
  • Is the accordion defaulted open or closed? – tuckerjt07 Jul 30 '15 at 08:24
  • by default accordion it is closed. – Aamir Faried Jul 30 '15 at 08:28
  • I wonder if you could call `checkResize()` on the map instance when the accordion is opened? See [this question](http://stackoverflow.com/questions/1746608/google-maps-not-rendering-completely-on-page) for more details. – djskinner Jul 30 '15 at 08:30
  • That's what I was anticipating. The accordions that are closed can cause all sorts of weird rendering and execution issues. If my memory serves me correctly they use a display: none; element to hide their content and as such this can throw a wrench into things. I don't have an elegant way to fix it off the top of my head and without tinkering I apologize. A hackish way would be default it to open, and then close it after it starts rendering via a $timeout in the controller. As I said that is a hack and far from a best practice though. – tuckerjt07 Jul 30 '15 at 08:32
  • tuckerjt07, if it is the case then why it is working second time when i come back to this page ? one important thing is that if I don't come through 'angular world' but instead enter link directly on browse.then it does not work even second time – Aamir Faried Jul 30 '15 at 09:21
  • djskinner, i m new to angular and googlemap, sorry if my question is stupid, but how to call method checkResize as i dont have map object what i have is this. $scope.localMap = { center: { latitude: 62.3875, longitude: 16.325556 }, mapInstance: null, zoom: 13, markers: [], refreshMap: true, events: { tilesloaded: function (map) { // this function is used to access the map instance - see documentation https://angular-ui.github.io/angular-google-maps/#!/faq $scope.$apply(function () { $scope.localMap.mapInstance = map; }); },}}; – Aamir Faried Jul 30 '15 at 09:44
  • I agree with @tuckerjt07 which is why I went to look for calls you could make to the google maps instance to force it to render. Once you have your `$scope.localMap.mapInstance` set try calling it on there. Also see what other methods are available. Basically you want to force it to render when the accordion opens. If you could create a code pen we may be able to help further. – djskinner Jul 30 '15 at 12:13

2 Answers2

0

I had the same problem where I had a div with an ng-show directive that evaluated to false initially on view-load and the Google Maps map element would get initialized on view-load, too. But the div I passed to Google Maps api to initialize the map element was inside the ng-show='false' div and the blank map would show.

I solved it by changing the initializing of the map element to when the ng-show directive evaluated to true.

I think it would be best if you created the Google Maps map element, when the accordion got opened.

I had it all in a custom directive so it was easy to put a scope-watch inside the link method of the directive. Posting code for future users who might come across same problem.

angular.app('module').directive('customDirective', function ($timeout) {
    return {
        template: '...',
        link: function(scope, element) {
            var mapInitialized = false; # To track if map has already been initialized.
            var mapOptions = {...};
            var initMap = function() {
                map = new google.maps.Map(element.find(".map-elem")[0], mapOptions);
                mapInitialized = true;
            };
            scope.$watch 'isMapElemContainerShown', function(newValue, oldValue) {
                if (newValue == oldValue) return;
                if (newValue && !mapInitialized) {
                    $timeout(initMap, 100); # Allow delay for view element to update to be visible. 
                }
            }
        }
    }
}
Xchai
  • 1,473
  • 1
  • 11
  • 10
0

You can use the control object (http://angular-ui.github.io/angular-google-maps/#!/api/google-map)

<ui-gmap-google-map center='center' control='control'>
</ui-gmap-google-map>

In your controller, specify an empty control object (it gets initialized automatically). Use it to refresh the map when the accordion opens.

$scope.control = {};

$scope.$watch("map.open", function (newVal) {
    if (newVal) {
        $timeout(function () {
            $scope.control.refresh(center);
        });
    }
});
user828878
  • 398
  • 4
  • 8