2016-12-22 4 views
1

データベースの値のセットから複数のベースレイヤーをセシウムマップに追加しようとしています。私はjavascriptを反復して追加するだけです。以下は、セシウムの静的コードの例です。Javascript closure:セシウムマップに動的baselayersを追加する方法

var imageryViewModels = []; 
imageryViewModels.push(new Cesium.ProviderViewModel({ 
    name : 'Open\u00adStreet\u00adMap', 
    iconUrl : Cesium.buildModuleUrl('openStreetMap.png'), 
    tooltip : 'OpenStreetMap (OSM)', 
    creationFunction : function() { 
     return Cesium.createOpenStreetMapImageryProvider({ 
      url : 'https://a.tile.openstreetmap.org/' 
     }); 
    } 
})); 

imageryViewModels.push(new Cesium.ProviderViewModel({ 
    name : 'Black Marble', 
    iconUrl : Cesium.buildModuleUrl('blackMarble.png'), 
    tooltip : 'outlines of civilization', 
    creationFunction : function() { 
     return Cesium.createTileMapServiceImageryProvider({ 
      url : 'https://cesiumjs.org/blackmarble', 
      credit : 'B Observatory', 
      flipXY : true 
     }); 
    } 
})); 

静的な値のセットを使用しています。ここでは難しいところですが、値のセットをループして、ProviderViewModelsを配列にプッシュします。このように -

var imageryViewModels = []; 
baseLayers = HashOfValuesFromDatabase; 
for(int i=0; i<baseLayers.length; i++{ 

    imageryViewModels.push(new Cesium.ProviderViewModel({ 
     name : baseLayers[i].name, 
     iconUrl : Cesium.buildModuleUrl(baseLayers[i].iconUrl), 
     tooltip : baseLayser[i].toolTip, 
     creationFunction : function() { 
      return Cesium.createOpenStreetMapImageryProvider({ 
       url : baseLayers[i].url // ***** this value always the last value **** 
      }); 
     } 
    })); 

} 

問題はjavascriptの閉鎖は私に問題を引き起こしていると私のimageryViewModelsの一人一人がbaseLayer.urlオブジェクトの最後の値であるということです。セシウムはこれを関数とする必要があります。これを関数にして、iterated baseLayer.urlの値を取得する方法はありますか?

答えて

2

ベンアストンの答えはここに正しいアプローチです。彼はそれを実行しようとしなかったし、}(i))の後ろに余分なセミコロンがあり、それは引数リストの中では不正であり、オリジナルの質問からコピーしたいくつかの問題もある。ここでは修正バージョンだ、と私はこれを実行になりました:

var imageryViewModels = []; 
for(var i=0; i<baseLayers.length; i++) { 

    imageryViewModels.push(new Cesium.ProviderViewModel({ 
     name : baseLayers[i].name, 
     iconUrl : Cesium.buildModuleUrl(baseLayers[i].iconUrl), 
     tooltip : baseLayers[i].toolTip, 
     creationFunction : (function(i) { 
      return function() { 
      return Cesium.createOpenStreetMapImageryProvider({ 
       url : baseLayers[i].url 
      }); 
      }; 
     }(i)) 
    })); 
} 

理由は、これはurlパラメータがあるため、パラメータとしてiを使用して生命維持(すぐに呼び出される関数式)である修正されています。これは、ループを介して反復ごとに新しいJavaScriptクロージャを作成します。これは高価ですが、各個別のcreate関数は、ループの特定の反復からのiという値の独自のコピーを持つ独自のクロージャを取得する必要があります。これがなければ、変数が1つだけの閉包が1つしかなく、作成関数のいずれかが実際に呼び出されるときまでに、ループは終了してから長くなり、iの値は最大に達しています。

2

この(私はそれを実行していない)してみてください:

var imageryViewModels = []; 
baseLayers = HashOfValuesFromDatabase; 
for(int i=0; i<baseLayers.length; i++{ 

    imageryViewModels.push(new Cesium.ProviderViewModel({ 
     name : baseLayers[i].name, 
     iconUrl : Cesium.buildModuleUrl(baseLayers[i].iconUrl), 
     tooltip : baseLayser[i].toolTip, 
     creationFunction : (function(i) { 
      return function() { 
      return Cesium.createOpenStreetMapImageryProvider({ 
       url : baseLayers[i].url 
      }); 
      } 
     }(i)) 
    })); 

} 

編集:正しい構文(emackeyをお願い致します)を

関連する問題