現在、1つのページに複数のGoogleマップをロードしようとしています。マップが現在のページにない限り、スクリプトをロードしたくないので、GoogleマップAPIスクリプトをHTMLコードに含めたくありません。私のマップは、google map APIスクリプトの遅延読み込みも実行する単一のディレクティブ内で呼び出されます。
だから私は周りを検索し、 解決策を見つけました を少し調整しましたが、私の問題は、1つのマップのみが読み込まれ、他のマップは読み込まれないことです。
私のHTMLは次のようになります。
<div id="mapParis" class="google-map" lat="48.833" long="2.333"></div>
<div id="mapWashington" class="google-map" lat="38.917" long="-77.000"></div>
<div id="mapTokyo" class="google-map" lat="35.667" long="139.750"></div>
そして指令:
// Google Map
app.directive('googleMap', ['$window', '$q', function( $window, $q ) {
function loadScript() {
console.log('loadScript');
// use global document since Angular's $document is weak
var s = document.createElement('script');
s.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap';
document.body.appendChild(s);
}
// Lazy loading of the script
function lazyLoadApi(key) {
console.log('lazyLoadApi');
var deferred = $q.defer();
$window.initMap = function () {
deferred.resolve();
};
if ( $window.attachEvent ) {
$window.attachEvent('onload', loadScript);
} else {
$window.addEventListener('load', loadScript, false);
}
return deferred.promise;
}
return {
restrict: 'C', // restrict by class name
scope: {
mapId: '@id', // map ID
lat: '@', // latitude
long: '@' // longitude
},
link: function($scope, elem, attrs) {
// Check if latitude and longitude are specified
if ( angular.isDefined($scope.lat) && angular.isDefined($scope.long) ) {
console.log('-----');
// Initialize the map
$scope.initialize = function() {
console.log($scope.mapId);
$scope.location = new google.maps.LatLng($scope.lat, $scope.long);
$scope.mapOptions = {
zoom: 6,
center: $scope.location
};
$scope.map = new google.maps.Map(document.getElementById($scope.mapId), $scope.mapOptions);
new google.maps.Marker({
position: $scope.location,
map: $scope.map,
});
}
// Check if google map API is ready to run
if ( $window.google && $window.google.maps ) {
console.log('gmaps already loaded');
// Google map already loaded
$scope.initialize();
} else {
lazyLoadApi().then(function () {
// Promised resolved
console.log('promise resolved');
if ( $window.google && $window.google.maps ) {
// Google map loaded
console.log('gmaps loaded');
$scope.initialize();
} else {
// Google map NOT loaded
console.log('gmaps not loaded');
}
}, function () {
// Promise rejected
console.log('promise rejected');
});
}
}
}
};
これは3つのマップを持つjsFiddleです。最後の1つだけがロードされていることがわかります。
http://jsfiddle.net/5Pk8f/1/
私は自分のスコープまたは約束が処理される方法で何か間違っていると思いますが、今のところ私はまったく考えていません...
ありがとう! (そしてごめんなさいあまり良くない英語)
更新として、ここで私が思いついた完全なソリューション:
http://plnkr.co/edit/1NpquJ?p=preview (@maurycy plunker)
// Lazy loading of Google Map API
app.service('loadGoogleMapAPI', ['$window', '$q',
function ( $window, $q ) {
var deferred = $q.defer();
// Load Google map API script
function loadScript() {
// Use global document since Angular's $document is weak
var script = document.createElement('script');
script.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap';
document.body.appendChild(script);
}
// Script loaded callback, send resolve
$window.initMap = function () {
deferred.resolve();
}
loadScript();
return deferred.promise;
}]);
// Google Map
app.directive('googleMap', ['$rootScope', 'loadGoogleMapAPI',
function( $rootScope, loadGoogleMapAPI ) {
return {
restrict: 'C', // restrict by class name
scope: {
mapId: '@id', // map ID
lat: '@', // latitude
long: '@' // longitude
},
link: function( $scope, elem, attrs ) {
// Check if latitude and longitude are specified
if ( angular.isDefined($scope.lat) && angular.isDefined($scope.long) ) {
// Initialize the map
$scope.initialize = function() {
$scope.location = new google.maps.LatLng($scope.lat, $scope.long);
$scope.mapOptions = {
zoom: 12,
center: $scope.location
};
$scope.map = new google.maps.Map(document.getElementById($scope.mapId), $scope.mapOptions);
new google.maps.Marker({
position: $scope.location,
map: $scope.map,
});
}
// Loads google map script
loadGoogleMapAPI.then(function () {
// Promised resolved
$scope.initialize();
}, function () {
// Promise rejected
});
}
}
};
}]);
<div id="mapParis" class="google-map" lat="48.833" long="2.333"></div>
<div id="mapWashington" class="google-map" lat="38.917" long="-77.000"></div>
<div id="mapTokyo" class="google-map" lat="35.667" long="139.750"></div>
敬意を表します
あなたはここで約束と初期化に問題があります、私はあなたのためにそれをよりきれいにしました
どうやらjsfiddleが削除されたので、ここで作業中のプランカーを使用します。 http://plnkr.co/edit/1NpquJ?p=preview
これは遅延ロードgmapsのサービスです
app.service('lazyLoadApi', function lazyLoadApi($window, $q) {
function loadScript() {
console.log('loadScript')
// use global document since Angular's $document is weak
var s = document.createElement('script')
s.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap'
document.body.appendChild(s)
}
var deferred = $q.defer()
$window.initMap = function () {
deferred.resolve()
}
if ($window.attachEvent) {
$window.attachEvent('onload', loadScript)
} else {
$window.addEventListener('load', loadScript, false)
}
return deferred.promise
});
次に、ディレクティブはそれがすべきことを行い、マップでのみ機能し、他のロジックでjsファイルをロードしません