ui-map.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. 'use strict';
  2. (function () {
  3. //Setup map events from a google map object to trigger on a given element too,
  4. //then we just use ui-event to catch events from an element
  5. function bindMapEvents(scope, eventsStr, googleObject, element) {
  6. angular.forEach(eventsStr.split(' '), function (eventName) {
  7. //Prefix all googlemap events with 'map-', so eg 'click'
  8. //for the googlemap doesn't interfere with a normal 'click' event
  9. window.google.maps.event.addListener(googleObject, eventName, function (event) {
  10. element.triggerHandler('map-' + eventName, event);
  11. //We create an $apply if it isn't happening. we need better support for this
  12. //We don't want to use timeout because tons of these events fire at once,
  13. //and we only need one $apply
  14. if (!scope.$$phase){ scope.$apply();}
  15. });
  16. });
  17. }
  18. app.value('uiMapConfig', {});
  19. app.directive('uiMap',
  20. ['uiMapConfig', '$parse', function (uiMapConfig, $parse) {
  21. var mapEvents = 'bounds_changed center_changed click dblclick drag dragend ' +
  22. 'dragstart heading_changed idle maptypeid_changed mousemove mouseout ' +
  23. 'mouseover projection_changed resize rightclick tilesloaded tilt_changed ' +
  24. 'zoom_changed';
  25. var options = uiMapConfig || {};
  26. return {
  27. restrict: 'A',
  28. //doesn't work as E for unknown reason
  29. link: function (scope, elm, attrs) {
  30. var opts = angular.extend({}, options, scope.$eval(attrs.uiOptions));
  31. var map = new window.google.maps.Map(elm[0], opts);
  32. var model = $parse(attrs.uiMap);
  33. //Set scope variable for the map
  34. model.assign(scope, map);
  35. bindMapEvents(scope, mapEvents, map, elm);
  36. }
  37. };
  38. }]);
  39. app.value('uiMapInfoWindowConfig', {});
  40. app.directive('uiMapInfoWindow',
  41. ['uiMapInfoWindowConfig', '$parse', '$compile', function (uiMapInfoWindowConfig, $parse, $compile) {
  42. var infoWindowEvents = 'closeclick content_change domready ' +
  43. 'position_changed zindex_changed';
  44. var options = uiMapInfoWindowConfig || {};
  45. return {
  46. link: function (scope, elm, attrs) {
  47. var opts = angular.extend({}, options, scope.$eval(attrs.uiOptions));
  48. opts.content = elm[0];
  49. var model = $parse(attrs.uiMapInfoWindow);
  50. var infoWindow = model(scope);
  51. if (!infoWindow) {
  52. infoWindow = new window.google.maps.InfoWindow(opts);
  53. model.assign(scope, infoWindow);
  54. }
  55. bindMapEvents(scope, infoWindowEvents, infoWindow, elm);
  56. /* The info window's contents dont' need to be on the dom anymore,
  57. google maps has them stored. So we just replace the infowindow element
  58. with an empty div. (we don't just straight remove it from the dom because
  59. straight removing things from the dom can mess up angular) */
  60. elm.replaceWith('<div></div>');
  61. //Decorate infoWindow.open to $compile contents before opening
  62. var _open = infoWindow.open;
  63. infoWindow.open = function open(a1, a2, a3, a4, a5, a6) {
  64. $compile(elm.contents())(scope);
  65. _open.call(infoWindow, a1, a2, a3, a4, a5, a6);
  66. };
  67. }
  68. };
  69. }]);
  70. /*
  71. * Map overlay directives all work the same. Take map marker for example
  72. * <ui-map-marker="myMarker"> will $watch 'myMarker' and each time it changes,
  73. * it will hook up myMarker's events to the directive dom element. Then
  74. * ui-event will be able to catch all of myMarker's events. Super simple.
  75. */
  76. function mapOverlayDirective(directiveName, events) {
  77. app.directive(directiveName, [function () {
  78. return {
  79. restrict: 'A',
  80. link: function (scope, elm, attrs) {
  81. scope.$watch(attrs[directiveName], function (newObject) {
  82. if (newObject) {
  83. bindMapEvents(scope, events, newObject, elm);
  84. }
  85. });
  86. }
  87. };
  88. }]);
  89. }
  90. mapOverlayDirective('uiMapMarker',
  91. 'animation_changed click clickable_changed cursor_changed ' +
  92. 'dblclick drag dragend draggable_changed dragstart flat_changed icon_changed ' +
  93. 'mousedown mouseout mouseover mouseup position_changed rightclick ' +
  94. 'shadow_changed shape_changed title_changed visible_changed zindex_changed');
  95. mapOverlayDirective('uiMapPolyline',
  96. 'click dblclick mousedown mousemove mouseout mouseover mouseup rightclick');
  97. mapOverlayDirective('uiMapPolygon',
  98. 'click dblclick mousedown mousemove mouseout mouseover mouseup rightclick');
  99. mapOverlayDirective('uiMapRectangle',
  100. 'bounds_changed click dblclick mousedown mousemove mouseout mouseover ' +
  101. 'mouseup rightclick');
  102. mapOverlayDirective('uiMapCircle',
  103. 'center_changed click dblclick mousedown mousemove ' +
  104. 'mouseout mouseover mouseup radius_changed rightclick');
  105. mapOverlayDirective('uiMapGroundOverlay',
  106. 'click dblclick');
  107. })();