Angularjs 如果不是从$timeout内部运行,函数将抛出错误

Angularjs 如果不是从$timeout内部运行,函数将抛出错误,angularjs,Angularjs,我的控制器中有这个代码 $scope.initMap = function() { var mapOptions = { center: new google.maps.LatLng(-34.397, 150.644), zoom: 8 }; var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions); } $timeout(

我的控制器中有这个代码

$scope.initMap = function() {
    var mapOptions = {
        center: new google.maps.LatLng(-34.397, 150.644),
        zoom: 8
    };      
    var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}

$timeout(function(){$scope.initMap();}, 1); //This works
//$scope.initMap(); //Doing it like this causes the crash
使用$timeout行可以很好地初始化映射,但是使用底线Angular会从缩小的库中的某个地方抛出一个错误
a is null

我将Google Maps js文件包含在HTML中控制器的正上方

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=MyKey& sensor=false"></script>
<div class="row" ng-controller="VenuesCtrl">


我假设这与$timeout函数有关,而不需要等待1毫秒,但我无法理解。我需要$timeout吗?或者我可以在没有它的情况下让代码正常工作吗?

这是因为Google试图在映射画布元素呈现之前使用IDDOM元素。我将创建一个指令并从那里调用GoogleMap构造函数

我认为即使使用
$timeout
0
它也可以工作

调用$timeout后每隔一段代码执行一次后,由
$timeout
包装的函数就会执行

为什么有效

使用timeout,您只需降低执行优先级。这是一个技巧,告诉浏览器在其他事情完成且浏览器不忙时尽快运行它


您可以在谷歌上搜索足够多的示例和演示如何使用指令编写谷歌地图构造函数。我用我自己的

以下是相关代码:

HTML

 <map-directive id="map_canvas" >                    
 </map-directive>

指令

app.directive('mapDirective', ['$log', function($log) {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            /* ... */
        },
        template: '<div></div>',
        link: function(scope, element, attrs) {


        var map = false;

       //...    


       initialize(document.getElementById(attrs.id));

     function initialize(map_id) {
        log.i("initialize Google maps");     


        var mapZoomLevel  = locStorage.get('mapZoomLevel', 12);
        var mapLast_lat =   locStorage.get('mapLast_lat', 34.060122481016855);
        var mapLast_longt = locStorage.get('mapLast_longt', -118.26350324225484);

        var options = {                                
            zoom: mapZoomLevel,
            center: new google.maps.LatLng(mapLast_lat, mapLast_longt),
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            panControl: false,
            scrollwheel: true,
            draggable: true,
            rotateControl: false,
            mapTypeControl: true,
            scaleControl: true,
            streetViewControl: true,
            zoomControl: true,
            disableDoubleClickZoom: false
        };

        map = new google.maps.Map(document.getElementById(attrs.id), options);
       //...
      }
app.directive('mapDirective',['$log',function($log){
返回{
限制:'E',
替换:正确,
范围:{
/* ... */
},
模板:“”,
链接:函数(范围、元素、属性){
var-map=false;
//...    
初始化(document.getElementById(attrs.id));
函数初始化(映射id){
log.i(“初始化谷歌地图”);
var mapZoomLevel=locStorage.get('mapZoomLevel',12);
var mapLast_lat=locStorage.get('mapLast_lat',34.060122481016855);
var mapLast_long=locStorage.get('mapLast_long',-118.26350324225484);
变量选项={
缩放:mapZoomLevel,
中心:新的google.maps.LatLng(mapLast_lat,mapLast_Long),
mapTypeId:google.maps.mapTypeId.ROADMAP,
泛控制:错误,
滚轮:对,
真的,
旋转控制:错误,
mapTypeControl:true,
scaleControl:对,
街景控制:对,
动物控制:对,
禁用双击缩放:false
};
map=new google.maps.map(document.getElementById(attrs.id),options);
//...
}

听起来像是这样,因为Google试图在呈现
映射画布
元素之前使用
id
DOM元素。我会创建指令并从中调用Google map构造函数,但是1毫秒的超时会使它及时呈现吗?奇怪的是,这么短的时间就能使它正常工作。在$timeout 0仍然可以正常工作。好的,谢谢,我将尝试该指令。是否可以向该指令传递类似于
map var=“map”
的属性,并且在我的控制器$scope.map中将是它渲染的映射?