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の外部で「map」にアクセスできるのに「bounds」にはアクセスできないのはなぜですか?
  2. よりスマートなパターン(モジュール)に従ってこのコードを書き直し、スクリプトの他の部分で境界を使用できるようにし、試行中に4つのプロパティを正常に追加できるようにするにはどうすればよいですか?

イベントが発生したことを編集します-手動で発生した後でも、空のオブジェクトを取得します:

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 に答える