source : map-lazy-load.js

  1. /**
  2. * @ngdoc directive
  3. * @name map-lazy-load
  4. * @param Attr2Options {service} convert html attribute to Google map api options
  5. * @description
  6. * Requires: Delay the initialization of map directive
  7. * until the map is ready to be rendered
  8. * Restrict To: Attribute
  9. *
  10. * @attr {String} map-lazy-load
  11. * Maps api script source file location.
  12. * Example:
  13. * 'https://maps.google.com/maps/api/js'
  14. * @attr {String} map-lazy-load-params
  15. * Maps api script source file location via angular scope variable.
  16. * Also requires the map-lazy-load attribute to be present in the directive.
  17. * Example: In your controller, set
  18. * $scope.googleMapsURL = 'https://maps.google.com/maps/api/js?v=3.20&client=XXXXXenter-api-key-hereXXXX'
  19. *
  20. * @example
  21. * Example:
  22. *
  23. * <div map-lazy-load="http://maps.google.com/maps/api/js">
  24. * <map center="Brampton" zoom="10">
  25. * <marker position="Brampton"></marker>
  26. * </map>
  27. * </div>
  28. *
  29. * <div map-lazy-load="http://maps.google.com/maps/api/js"
  30. * map-lazy-load-params="">
  31. * <map center="Brampton" zoom="10">
  32. * <marker position="Brampton"></marker>
  33. * </map>
  34. * </div>
  35. */
  36. /* global window, document */
  37. (function() {
  38. 'use strict';
  39. var $timeout, $compile, src, savedHtml = [], elements = [];
  40. var preLinkFunc = function(scope, element, attrs) {
  41. var mapsUrl = attrs.mapLazyLoadParams || attrs.mapLazyLoad;
  42. if(window.google === undefined || window.google.maps === undefined) {
  43. elements.push({
  44. scope: scope,
  45. element: element,
  46. savedHtml: savedHtml[elements.length],
  47. });
  48. window.lazyLoadCallback = function() {
  49. console.log('Google maps script loaded:', mapsUrl);
  50. $timeout(function() { /* give some time to load */
  51. elements.forEach(function(elm) {
  52. elm.element.html(elm.savedHtml);
  53. $compile(elm.element.contents())(elm.scope);
  54. });
  55. }, 100);
  56. };
  57. var scriptEl = document.createElement('script');
  58. console.log('Prelinking script loaded,' + src);
  59. scriptEl.src = mapsUrl +
  60. (mapsUrl.indexOf('?') > -1 ? '&' : '?') +
  61. 'callback=lazyLoadCallback';
  62. if (!document.querySelector('script[src="' + scriptEl.src + '"]')) {
  63. document.body.appendChild(scriptEl);
  64. }
  65. } else {
  66. element.html(savedHtml);
  67. $compile(element.contents())(scope);
  68. }
  69. };
  70. var compileFunc = function(tElement, tAttrs) {
  71. (!tAttrs.mapLazyLoad) && console.error('requires src with map-lazy-load');
  72. savedHtml.push(tElement.html());
  73. src = tAttrs.mapLazyLoad;
  74. /**
  75. * if already loaded, stop processing it
  76. */
  77. if(window.google !== undefined && window.google.maps !== undefined) {
  78. return false;
  79. }
  80. tElement.html(''); // will compile again after script is loaded
  81. return {
  82. pre: preLinkFunc
  83. };
  84. };
  85. var mapLazyLoad = function(_$compile_, _$timeout_) {
  86. $compile = _$compile_, $timeout = _$timeout_;
  87. return {
  88. compile: compileFunc
  89. };
  90. };
  91. mapLazyLoad.$inject = ['$compile','$timeout'];
  92. angular.module('ngMap').directive('mapLazyLoad', mapLazyLoad);
  93. })();