0

我有以下JS:

Meteor.startup(function () {
  map = L.map('map_canvas').locate({setView: true, maxZoom: 21});
  L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map);
    bounds = {};    
    map.on('locationfound', function(e){ 
      bounds.bottomLeftLat = map.getBounds()._southWest.lat;
      bounds.bottomLeftLng = map.getBounds()._southWest.lng;
      bounds.topRightLat = map.getBounds()._northEast.lat;
      bounds.topRightLng = map.getBounds()._northEast.lng;
      console.log(bounds);
    });
  console.log('outside function: '+bounds);
});

我的第一个 console.log 在控制台中正确输出了 4 个对象属性及其值,但是外部函数日志输出一个空对象,当我尝试访问 Meteor.startup 之外的边界时,它甚至都没有定义。我知道函数限制了变量的范围,但是如果在匿名函数之外定义了边界,没有'var',它不被认为是全局的吗?

  1. 为什么我可以在 Meteor.startup 之外访问“地图”而不是“边界”?
  2. 如何通过遵循更多智能模式(模块?)来重写此代码,以便我既可以在脚本的其他部分提供边界,又可以在尝试时成功添加四个属性?

编辑事件被触发 - 手动触发后,我仍然得到一个空对象:

map.fire("locationfound");
Object {type: "locationfound", target: e, bottomLeftLat: 50.05008477838258, bottomLeftLng: 0.384521484375, topRightLat: 51.63847621195153…}
 MainClient.js:12
e {options: Object, _container: div#map_canvas.leaflet-container leaflet-fade-anim, _panes: Object, _mapPane: div.leaflet-map-pane, _tilePane: div.leaflet-tile-pane…}
bounds
Object {}
4

2 回答 2

2

它正在查看,bounds但您console.log在事件回调之前locationfound发生,因此当您尝试访问它时它仍然是空的。

您的所有初始化都将在事件第一次locationfound触发时发生,此时的日志将显示您期望的结果。

一些想法。

  1. 一般来说,不赞成声明变量var。如果要全局访问它,请var在全局上下文中声明它,或者(理想情况下)使用命名空间变量并将所有全局变量声明为它的属性。

  2. 如果要在修改后访问边界,可以将调用放在回调中要运行的函数

更新以阐明您的代码的行为

这是您的代码的执行方式。

//This is the startup function for meteor.  It is passed a function, 
//and executes that function when the code starts up
Meteor.startup(function () {
    //You're now inside the function you passed to startup, and you initialize map
    //...
    bounds = {};    
    //here you call the `on` function on map, and bind a 
    //callback function to the locationfound event
    map.on('locationfound', function(e){ 
      //This code is inside the callback and will be executed when the event occurs 
      
      // code initializing bounds

      console.log(bounds); //this will show the full definition of bounds
      //callback ends here
    });
  //this is outside the callback but still inside startup, 
  //and occurs immediately after the call to map.on
  console.log('outside function: '+bounds); //bounds is still empty
}); //end the startup function

看来您需要了解的关键是on功能。它是一个传单函数,它接受 2 个参数,一个事件类型和一个回调函数,并将回调函数绑定到事件。然后回调函数在事件发生时运行,而不是之前。回调不会立即运行。相反,代码继续执行,并在事件发生时执行回调代码。

文档on

于 2013-03-20T19:48:37.337 回答
1

这就是所谓的javascript事件循环 “地图”之外的代码可以访问边界变量,但是您在定义地图的locationfound事件后立即尝试访问它-边界仅在此事件发生时才初始化-那么是什么您进入控制台只是您在 "bounds = "{}" 之前定义的一个空对象

您所做的是正确的-您只能在 locationfound 事件中访问边界,因为只有在初始化它之后

于 2013-03-20T19:51:24.400 回答