I need to get the handle of a marker in order to set the icon when I have a ng-mouseover somewhere else on the page.
I push my markers into leaflet like this:
angular.extend($scope,
{markers:
{'id1': {lat:foo, lng:bar},
'id2': {lat:foo, lng:bar}, ...
}
});
$scope.markers['id1'] returns the correct lat/lng dict. Here, i need the marker object so I can perform a marker.setIcon().
Looked a little into leafletMarkersHelpers but no success ...
Would appreciate any starting point.
Thanx
Best
/B
There's an leafletData service for that. The Promise you get when you call leafletData.getMarkers() resolves with the Leaflet marker objects in the object with keys like in your scope.
leafletData.getMarkers().then(function (markers) {
markers.id1.setIcon(...);
});
Related
I'm using Angular Leaflet Directive. In the example, say here form the docs (http://tombatossals.github.io/angular-leaflet-directive/#!/examples/dragging-markers), we have a marker that is draggable. Changing the location of the draggable Madrid marker is possible by clicking up and down on the lat/lng input.
Is there a way for the reverse to happen? That is, when the marker is dragged, the location is updated in those input values?
Alternately, is there a way to access a specific marker and retrieve its coordinates with the directive?
you should take a look at this link: http://tombatossals.github.io/angular-leaflet-directive/examples/0500-markers-simple-example.html
Specifically at those lines:
$scope.$on("leafletDirectiveMarker.dragend", function(event, args){
$scope.position.lat = args.model.lat;
$scope.position.lng = args.model.lng;
});
There is also a marker ID, if you have more than one marker on the map.
Also, you should know that when you drag marker, lat/lng properties of that marker update themselves, so you can use simple $watch, too.
Having trouble with always rendering google maps in my Ionic app. When I first land on a view from a list of items on the previous view, the map always renders in its complete state. However, if I go back to the previous view and tap a different business, or even the same one, it appears as if the map is only rendering 25% of the complete map. I'm having this issue on both the emulator and on my iPhone.
Example
Code
getData.getBusinesses()
.then(function(data) {
// get businesses data from getData factory
})
.then(function(data) {
// get businesses photo from getData factory
})
.then(function(data) {
// get some other business stuff
})
.then(function() {
// get reviews for current business from separate async call in reviews factory
})
.then(function() {
// instantiate our map
var map = new GoogleMap($scope.business.name, $scope.business.addr1, $scope.business.city, $scope.business.state, $scope.business.zip, $scope.business.lat, $scope.business.long);
map.initialize();
})
.then(function() {
// okay, hide loading icon and show view now
},
function(err) {
// log an error if something goes wrong
});
What doesn't make sense to me is that I'm using this exact code for a website equivalent of the app, yet the maps fully load in the browser every time. The maps also fully load when I do an ionic serve and test the app in Chrome. I did also try returning the map and initializing it in a following promise, but to no avail.
I've also tried using angular google maps, but the same issue is occurring. I think I might want to refactor my gmaps.js (where I'm creating the Google Maps function) into a directive, but I don't know if that will actually fix anything (seeing as angular google maps had the same rendering issue).
I don't think the full code is necessary, but if you need to see more let me know.
EDIT
It seems that wrapping my map call in a setTimeout for 100ms always renders the map now. So I guess the new question is, what's the angular way of doing this?
I'm seeing similar issues with ng-map in Ionic. I have a map inside of a tab view and upon switching tabs away from the map view and back again, I would often see the poorly rendered and greyed out map as you describe above. Two things that I did that may help fix your issue:
Try using $state.go('yourStateHere', {}, {reload: true}); to get back to your view. The reload: true seemed to help re-render the map properly when the map was within the tab's template.
After wrapping the map in my own directive, I found the same thing happening again and wasn't able to fix it with the first suggestion. To fix it this time, I started with #Fernando's suggestion and added his suggested $ionicView.enter event to my directive's controller. When that didn't work, I instead added a simple ng-if="vm.displayMap" directive to the <ng-map> directive and added the following code to add it to the DOM on controller activation and remove it from the DOM right before leaving the view.
function controller($scope) {
vm.displayMap = true;
$scope.$on('$ionicView.beforeLeave', function(){
vm.displayMap = false;
});
}
Hope that helps.
don't use setTimeout on this!
You need to understand that the map is conflicting with the container size or something (example: map is loading while ionic animation is running, like swiping).
Once you understand this, you need to set map after view is completely rendered.
Try this on your controller:
$scope.$on('$ionicView.enter', function(){
var map = new GoogleMap($scope.business.name,
$scope.business.addr1, $scope.business.city,
$scope.business.state, $scope.business.zip,
$scope.business.lat, $scope.business.long);
map.initialize();
});
I' was trying out angular map and I faced a problem which was related to getting map marker position and display it when marker is moved. But marker model was not updated when marker was moved. I used the official example and solve the problem by changing the dragend event. I used the apply to change the marker coordinates value
events: {
dragend: function (marker, eventName, args) {
$log.log('marker dragend');
$log.log(marker.getPosition().lat());
$log.log(marker.getPosition().lng());
$scope.$apply(function(){
$scope.marker.coords.latitude = marker.getPosition().lat();
$scope.marker.coords.longitude = marker.getPosition().lng();
});
}
}
The complete example can be seen here.
But I'm not satisfied with this approach. Is there any solution where I do not need to put in this block to update marker coords
$scope.$apply(function(){
$scope.marker.coords.latitude = marker.getPosition().lat();
$scope.marker.coords.longitude = marker.getPosition().lng();
});
There are two ways to send updated data to your directive.
$apply: If you want to update data which is coming from parent controller and other directives are also using the same then use this. However, after this function $digest will call to update local variables.
$digest: If you want to update directive level scope variables then you can directly call this method.
Thanks to #AJoslin I now have a working google map using only AngularUI and AngularJS.
Unfortunately there are two things I can't figure out how to do which may have to do with Google Map API and my lack of understanding of.
When the map initially loads, I already have a location so I wish to load it with a marker already on it. How do I do that?
I also wish to set the ng-click="myMap.panTo(marker.getPosition()) not to a new marker but to the initial location, which is the only marker I would have since I'm removing the add marker functionality out, once I can figure this one out.
Here is the working jsfiddle
http://jsfiddle.net/jorgecas99/xMw6U/
i think it should be achievable by setting the tilesloaded event, but didnt manage that way, so i ended up using a simple "trick", watching for myMap to appear.
$scope.$watch('myMap', function(){
$scope.setHome();
});
$scope.setHome = function() {
$scope.homeMarker = new google.maps.Marker({
map: $scope.myMap,
position: $scope.mapOptions.center
});
}
So today I just came across the 'live()' function that binds any future and past elements to the whatever event you choose, such as 'onclick'.
Right now I'm having to set up buttons like the following each time I load a new button via ajax ...
$('a.btn.plus').button({icons:{primary:'ui-icon-plusthick'}});
$('a.btn.pencil').button({icons:{primary:'ui-icon ui-icon-pencil'}});
$('a.btn.bigx').button({icons:{primary:'ui-icon ui-icon-closethick'}});
So, instead of calling these lines each time I use ajax to add a new button, is there a similar way to tell JQuery to setup my buttons ANYTIME I add new ones?
Thanks for any help!
Mmh not really. But there is the function .ajaxSuccess() which is triggered whenever an Ajax call is successful. So you could do:
$('body').ajaxSuccess(function() {
$('a.btn.plus').button({icons:{primary:'ui-icon-plusthick'}});
$('a.btn.pencil').button({icons:{primary:'ui-icon ui-icon-pencil'}});
$('a.btn.bigx').button({icons:{primary:'ui-icon ui-icon-closethick'}});
});
But this will run on any links with the classes, not only on the new ones. But if you append them on a time (i.e. not multiple a.btn.plus at once) you might be able to use the :last selector (a.btn.plus:last).
You can also create a function and just that from your callback functions:
function links() {
$('a.btn.plus').button({icons:{primary:'ui-icon-plusthick'}});
$('a.btn.pencil').button({icons:{primary:'ui-icon ui-icon-pencil'}});
$('a.btn.bigx').button({icons:{primary:'ui-icon ui-icon-closethick'}});
}
and in the Ajax call:
$.ajax({
//...
success: function(msg){
links();
}
});
This way you can pass the parent element to the function in order to find the link only inside this element (so the code would only work on the new links).
A last option would be generate a custom event but in the end this would be similar to just doing a function call in your case so you gain not much.
You can use delegate in your success function too
$("body").delegate("a.btn", "hover", function(){
$(this).toggleClass("hover");
});
There is a Jquery Plugin called livequery which covers your requirements.
I like to think of this plugin as Jquery .live() but without the need for an event ('click') etc.
You can find more info here//
Jquery - Live Query Plugin