Angular function start google-maps ONCE after loading the initial map

using angular-google-maps to include google map in app

I need a command that will start the ONCE function after the initial loading of the map is completed - but only at the initial loading, not after each manipulation of the map

I can not use idle or tilesloaded , as they are launched after each movement ...

The function I want to run is to get the map borders in order to pull data from the server when the page loads - I want this to happen ONCE on the boot, then do the manual function by updating map-control
- if I use idle or tilesloaded to start it, it will pull out server data every time the user moves the map.

Does anyone know how to run a shutdown command to get map information (borders, etc.) after loading the initial map?

I tried putting maps.getBounds() in the second promise function, but it does not work.

Notice I have a fiddle working here - I just can no longer chain promises after the controls are $scope.map / options, etc., because they do not return a promise:

The sample code in the docs does not show how to bind a promise after defining $scope.map .

HTML

 <div class="angular-google-map-container" ng-controller="MainCtrl"> <ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="map.options" events="map.events" control="googlemap"> </ui-gmap-google-map> </div> 

controller

 myApp.controller('MainCtrl', function($scope, uiGmapGoogleMapApi) { uiGmapGoogleMapApi .then(function(maps){ $scope.map = { center: { latitude: 37.7749295, longitude: -122.4194155 }, zoom: 12 events: { tilesloaded: function (maps, eventName, args) { myServiceFuntion(maps) // this work fine but fires every time }, dragend: function (maps, eventName, args) { myServiceFuntion(maps) // this work fine but fires every time }, zoom_changed: function (maps, eventName, args) { myServiceFuntion(maps) // this work fine but fires every time } } } $scope.bounds = maps.getBounds() // this gives me 'getBounds() not a function' myServiceFuntion(maps); // this gives an error... ? return maps; //no promise returned here so no chance to delay the function below }) .then(function(maps){ //is this where i need to put my function ? doesn't delay on map load since no promise returned... }); }); 

Obviously, the maps object returned by the uiGmapGoogleMapApi promise is completely different from the maps object returned by events such as tilesloaded , etc ... quite confusing.

In addition, the FAQ only indicates how to use tilesloaded to obtain an instance of the map - which does not work for the reasons already described.

+6
source share
2 answers

The β€œcorrect” method, I believe, is to use the IsReady API function by injecting the uiGmapIsReady service into the controller. See the documentation .

With the promise of uiGmapIsReady you can pass map function / service, etc. with type code:

 uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map .then(function(instances) { // instances is an array object var maps = instances[0].map; // if only 1 map it found at index 0 of array $scope.myOnceOnlyFunction(maps); // pass the map to your function }); 

You can also iterate through the instances array to launch functions on each map (if more than one map is loaded on your page):

 uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map .then(function(instances) { // instances is an array object angular.forEach(instances, function(value, key) { var maps = value.map; $scope.myOnceOnlyFunction(maps); // will apply this function to each map }); }); 

then the whole controller will look like

 myApp.controller('MainCtrl', function($scope, uiGmapGoogleMapApi, uiGmapIsReady) { uiGmapGoogleMapApi .then(function(maps){ $scope.googlemap = {}; $scope.map = { center: { latitude: 37.7749295, longitude: -122.4194155 }, zoom: 13, pan: 1, options: myAppServices.getMapOptions().mapOptions, control: {}, events: { tilesloaded: function (maps, eventName, args) { }, dragend: function (maps, eventName, args) { }, zoom_changed: function (maps, eventName, args) { } } }; }); uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map .then(function(instances) { // instances is an array object var maps = instances[0].map; // if only 1 map it found at index 0 of array $scope.myOnceOnlyFunction(maps); // this function will only be applied on initial map load (once ready) }); $scope.myOnceOnlyFunction = function(maps){ // this will only be run once on initial load var center = maps.getCenter(); // examples of 'map' manipulation var lat = center.lat(); var lng = center.lng(); alert('I\'ll only say this once ! \n Lat : ' + lat + '\n Lng : ' + lng); }; }); 

jsfiddle


... not sure why this is not mentioned in the FAQ: ' How do I access an instance of a map? '- or why use tilesloaded ( which is considered unreliable ) instead of idle or uiGmapIsReady ...?
Perhaps the FAQ was really β€œ how can I access the map on an ongoing basis ?”


+9
source

How Sal Niro to indicate in another answer - one way to bypass the constant call to tilesloaded or idle is to define the variable and then mark it as true when you first run the events functions.

A bit hacky and surprising that the API does not have a method of accessing the map object after the initial loading of the map from the controller ... but it works.

However - adding this answer, since it is not practical to put your entire controller in a function (or condition) - there are some functions that you might want to name constantly. So just define the "run once" variable inside your controller before calling your card.

Solution :
Define a variable (here arbitrarily called "initialMapLoad") set to false or 0 :
var initialMapLoad = 0

Then, in the definition of Google Maps events (for example, tilesloaded , dragend or idle ), you can place the functions that you want to run only once, within the conditional:

 if(initialMapLoad === 0) { my_single_run_function(); var initialMapLoad = 1 } 

Remember to override the initialMapLoad variable to 1 or true after running your function.

Example:

 myApp.controller('MainCtrl', function($scope, uiGmapGoogleMapApi) { var initialMapLoad = 0; uiGmapGoogleMapApi .then(function(maps){ $scope.map = { center: { latitude: 37.7749295, longitude: -122.4194155 }, zoom: 13, events: { tilesloaded: function (maps, eventName, args) { // functions that run every time alert('I say this after every tile load'); if(initialMapLoad === 0){ // functions that run only once alert('I only say this once' + maps.getBounds()); initialMapLoad = 1; } }, } }; }) }); 

See a working example in this jsfiddle

+1
source

Source: https://habr.com/ru/post/981794/


All Articles