【问题标题】:Initialize Google Map in AngularJS在 AngularJS 中初始化谷歌地图
【发布时间】:2012-06-26 04:50:33
【问题描述】:

我正在考虑从backbonejs 迁移到angularjs。

在主干中,我可以初始化一个视图,然后创建一个谷歌地图实例。然后我可以平移/缩放/等并在视图之间切换,而不会丢失地图的当前状态。

使用 angularjs 给出以下内容:

layout.html

<body>
  <div class="container-fluid" ng-view></div>

map.html

<div id="map_canvas" ng-controller="MapCtrl"></div>

我能够创建一个指令来渲染地图就好了。问题是每次我切换回地图视图时它都会重新加载地图。

<map></map>

所以根据我对 Angular 的了解,我想我会创建一个 MapController 并在那里初始化地图。没有成功。

底线是我需要异步初始化一个谷歌地图并将数据推送到本地或远程,并且能够导航应用程序而无需每次都从头开始重新加载地图。

有人可以建议正确的方法吗?

谢谢你:)

根据 Andy Joslin 的建议尝试:

在 app.js 中:

// Generated by CoffeeScript 1.3.3
(function() {
  "use strict";

  angular.module("ofm", ["ofm.filters", "GoogleMaps", "ofm.directives"]).config([
    "$routeProvider", "$locationProvider", function($routeProvider, $locationProvider) {
      $routeProvider.when("/", {
        templateUrl: "partials/home"
      }).when("/map", {
        templateUrl: "partials/map",
        controller: MapCtrl
      }).otherwise({
        redirectTo: "/"
      });
      return $locationProvider.html5Mode(true);
    }
  ]);

}).call(this);

在 services.js 中:

angular.module('GoogleMaps', []).
  factory('wasMapInitialized', function() {
    console.log("inside service");
    var maps = 0;

    if (!maps) {
      maps += 1;
      return 0;
    } else {
      return 1;
    }
  });

在 controllers.js 中:

function MapCtrl($scope) {
  if (!GoogleMaps.wasMapInitialized()) {
    var lat = 46.87916;
    var lng = -3.32910;
    var map_id = '#map';
    initialize(map_id, lat, lng);
  }
  function initialize(map_id, lat, lng) {
    var myOptions = {
      zoom : 8,
      center : new google.maps.LatLng(lat, lng),
      mapTypeId : google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map($(map_id)[0], myOptions);
  }
}

在 map.html 中

#map
<div ng-controller="MapCtrl"></div>

我收到错误:未知提供者:GoogleMapsProvider

【问题讨论】:

  • +1。也想知道答案。
  • 我创建了一个项目angular-google-maps,并不断改进。见live version
  • 太好了,已经在我的观察名单上。 :)
  • @LarryEitel 你应该接受安迪的回答
  • 我无法让它在 AngularJS 1.0.8 和 Google Maps API v3 中以最轻微的方式工作。

标签: google-maps angularjs


【解决方案1】:

由于视图会在视图更改时创建和销毁控制器,因此您希望您的地图数据可以保存在其他地方。尝试创建一个 GoogleMap 服务来存储数据。

myApp.factory('GoogleMaps', function() {
  var maps = {};

  function addMap(mapId) {
    maps[mapId] = {};
  }
  function getMap(mapId) {
    if (!maps[mapId]) addMap(mapId);
    return maps[mapId];
  }

  return {
    addMap: addMap,
    getMap: getMap
  }
});

function MyController($scope, GoogleMaps) {
  //Each time the view is switched to this, retrieve supermanMap
  $scope.map = GoogleMaps.getMap('supermanMap');

  $scope.editMap = function() {
    $scope.map.kryptonite = true;
  };
}

如果您不喜欢这个解决方案,也有其他方法可以解决。

【讨论】:

  • 您能否简要介绍其他选项(仅命名它们)?谢谢。
  • 您可以在 $rootScope 中创建永远不会被破坏的地图,并让子作用域继承它。您也不能使用 ng-view ,因此范围和 dom 元素不会被创建破坏,而是显示和隐藏,但您必须滚动自己的路由系统。您还可以创建一个映射的东西,它只是一个普通的旧 JavaScript 对象,它在您的角度控制器引用的角度之外(但这实际上只是一种糟糕的服务方式)
  • 安迪,非常高兴你提出一些想法。我在 Angular 很年轻。你有机会举出一个例子吗?我被困在泥泞中,旋转着我的轮子。谢谢你:)
  • 您的服务初始化错误。这是一个 JSFiddle 示例:jsfiddle.net/mL34U
  • 安迪,非常感谢。你的建议效果很好。我会尽快发布实际使用的代码。
【解决方案2】:

这就是我在 Backbone 中所做的,以保留视图而不是破坏它。假设你有一个 id="container" 的 div 并且你的路由器有相应的路由。

routes: {
    "":"home",
    "map": "showMap"
},

showMap: function() {
    $("#container").children().detach();
    if(!this.mapView) {
        this.mapView = new MapView(); 
        this.mapView.render();
    }
    $("#container").html(this.mapView.el);
}

【讨论】:

  • 谢谢 Jerry,您的解决方案是在骨干中,而不是 angularjs。
【解决方案3】:

这是我将 maps api 与 Angularjs routeProvider 一起使用的解决方案: 在您的索引中,您必须添加:

angular-google-maps.min.js 和 lodash.min.js

在 application.js 中:

(function() {

var app = angular.module("myApp", ["ngRoute", "uiGmapgoogle-maps"]);


app.config(function(uiGmapGoogleMapApiProvider) {
    uiGmapGoogleMapApiProvider.configure({
        key: 'YOUR KEY HERE',
        v: '3.17',
        libraries: 'weather,geometry,visualization'
    });
});

app.config(function($routeProvider) {
    $routeProvider
        .when("/home", {
            templateUrl: "home.html",
            controller: "HomeController"
        })
        .when("/workwith", {
            templateUrl: "workwith.html",
            controller: "WorkwithController"
        })




    .otherwise({
        redirectTo: "/home"
    });

});

})();

最后但并非最不重要的是在您的控制器中:

(function() {
var app = angular.module("myApp");
var MyController = function($scope, $http, $log, $location, $routeParams, uiGmapGoogleMapApi) {
    $log.info("MyController");
    $log.info($routeParams);

    // Define variables for our Map object
    var areaLat = 44.2126995,
        areaLng = -100.2471641,
        areaZoom = 3;

    uiGmapGoogleMapApi.then(function(maps) {
        $scope.map = {
            center: {
                latitude: areaLat,
                longitude: areaLng
            },
            zoom: areaZoom
        };
        $scope.options = {
            scrollwheel: false
        };
    });    
 };
app.controller("MyController", MyController);

})();

【讨论】:

    【解决方案4】:

    大家好,Larry Eitel 和大家,我有以下方法:

    首先,我们需要创建一些全局变量:

    var mapGlobal, flag=0, CurrentmapNode;
    

    然后在Controller:

        function MapCtrl($scope) {
        var lat = 46.87916;
        var lng = -3.32910;
        var map_id = '#map';
    
         if (flag==0)
           initMap(mapId, lat, lng);
         else
           reinitMap(mapId);
    
      function initMap(map_id, lat, lng) {
        var myOptions = {
          zoom : 8,
          center : new google.maps.LatLng(lat, lng),
          mapTypeId : google.maps.MapTypeId.ROADMAP
        };
        mapGlobal = new google.maps.Map($(map_id)[0], myOptions);
    
        if (typeof mapGlobal != 'undefined')
           flag=1;
      }
    
      function reinitMap(mapId){
         $(mapId)[0].append(CurrentmapNode);
       }
    
       $scope.$on("$destroy", function(){
            CurrentmapNode = mapGlobal.getDiv(); //save current map in an auxiliar variable
       });
    
    }
    

    “on destroy”函数将当前地图状态保存在另一个全局变量中,然后,当重新创建视图时,我们不需要创建另一个地图实例。

    每次重新创建视图时,创建另一个地图实例可能会导致内存泄漏并增加 Google 地图 API 的使用量。

    最好的问候

    【讨论】:

      猜你喜欢
      • 2017-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多