2014-09-03 98 views
1

我正在尋找基於識別任務的結果查詢圖層的任何附件。如果圖層上有附件,我想將鏈接添加到infoTemplate的底部。如何處理嵌套的Dojo延遲

我在處理多個dojo延遲對象時遇到了問題。我知道他們正在解決,因爲返回值記錄在控制檯中,但我的infoWindow從不填充。

那麼處理幾個嵌套延期的正確方法是什麼?延期列表似乎是朝着正確方向邁出的一步,但我不確定在這種情況下我將如何格式化。

感謝,

更新:

我在下面更新了我的工作代碼。

map.on('click',executeIdentify); 

function executeIdentify(evt) { 
    identifyParams.width = map.width; 
    identifyParams.height = map.height; 
    identifyParams.geometry = evt.mapPoint; 
    identifyParams.mapExtent = map.extent; 

    var deferred = identifyTask.execute(identifyParams); 

    deferred.addCallback(function(deferredResult){ 
    var promiseList = [] 
    var features = array.map(deferredResult,function(result) { 

     var feature = result.feature; 
     var content = ""; 
     array.forEach(Object.keys(feature.attributes),function(attr) { 
     content += attr + ": " + feature.attributes[attr] + "<br>" 
     }); 
     var url = identifyTask.url + "/" + result.layerId + "/" + result.feature.attributes.OBJECTID + "/attachments?f=json" 
     var req = esriRequest({url:url}).then(function(newDef) { 

     if (Object.keys(newDef).toString() == "attachmentInfos,_ssl") { 
      content += "<br><b>Attachments:</b><hr>" 
      array.forEach(newDef.attachmentInfos,function(attach) { 
      content += "<a href=" + identifyTask.url + "/" + result.layerId + "/" + result.feature.attributes.OBJECTID + "/attachments/" + attach.id + " target='_blank'>" + attach.name + "</a><br>" 
      }) 
     } 
     content += "<br><br>"; 
     console.log(result) 
     feature.infoTemplate = new InfoTemplate(result.layerName + " " + result.feature.attributes.OBJECTID,content) 
     // console.log(feature) 
     return feature 
     },function(newDef) { 
     feature.infoTemplate = new InfoTemplate(result.layerName + " " + result.feature.attributes.OBJECTID,content); 
     // console.log(feature) 
     return feature 
     }); 
     promiseList.push(req); 
    }); 
    var promiseAll = new all(promiseList) 
    promiseAll.then(function(r) {promiseFun(r)}) 
    }) 
    function promiseFun(r) { 
    map.infoWindow.setFeatures(r); 
    map.infoWindow.show(evt.mapPoint); 
    } 
} 

回答

3

您應該看看使用dojo/promise/all來處理多個延遲結果。這裏有一個使用它來返回多個服務的結果的示例,還有一些額外的代碼來確定結果來自哪個服務。

<!DOCTYPE html> 
<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
     on iOS devices--> 
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"> 
    <title>Identify with Popup</title> 

    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css"> 
    <style> 
     html, body, #map { 
      height: 100%; 
      width: 100%; 
      margin: 0; 
      padding: 0; 
     } 
    </style> 

    <script>var dojoConfig = { parseOnLoad: true };</script> 
    <script src="http://js.arcgis.com/3.8/"></script> 
    <script> 

     var map; 
     var identifyTask, identifyParams, idPoint; 
     var identifyResults; 

     require([ 
      "esri/map", "esri/dijit/Popup", "dojo/promise/all", "dojo/domReady!" 
     ], function ( 
      Map, Popup, All 
     ) { 
      var popup = new Popup({ 
       fillSymbol: new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25])) 
      }, dojo.create("div")); 

      map = new Map("map", { 
       basemap: "satellite", 
       center: [-83.275, 42.573], 
       zoom: 18, 
       infoWindow: popup 
      }); 

      dojo.connect(map, "onLoad", mapReady); 

      var landBaseLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer", { opacity: .55 }); 
      map.addLayer(landBaseLayer); 

      var militaryLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/MapServer", { opacity: .55 }); 
      map.addLayer(militaryLayer); 


      function mapReady(map) { 
       dojo.connect(map, "onClick", runIdentifies); 
      } 

      function runIdentifies(evt) { 
       identifyResults = []; 
       idPoint = evt.mapPoint; 
       var layers = dojo.map(map.layerIds, function (layerId) { 
        return map.getLayer(layerId); 
       }); 
       layers = dojo.filter(layers, function (layer) { 
        if (layer.visibleLayers[0] !== -1) { 
         return layer.getImageUrl && layer.visible 
        } 
       }); //Only dynamic layers have the getImageUrl function. Filter so you only query visible dynamic layers 
       var tasks = dojo.map(layers, function (layer) { 
        return new esri.tasks.IdentifyTask(layer.url); 
       }); //map each visible dynamic layer to a new identify task, using the layer url 
       var defTasks = dojo.map(tasks, function (task) { 
        return new dojo.Deferred(); 
       }); //map each identify task to a new dojo.Deferred 
       var params = createIdentifyParams(layers, evt); 

       var promises = []; 

       for (i = 0; i < tasks.length; i++) { 
        promises.push(tasks[i].execute(params[i])); //Execute each task 
       } 

       var allPromises = new All(promises); 
       allPromises.then(function (r) { showIdentifyResults(r, tasks); }); 
      } 

      function showIdentifyResults(r, tasks) { 
       var results = []; 
       var taskUrls = []; 
       r = dojo.filter(r, function (result) { 
        return r[0]; 
       }); 
       for (i = 0; i < r.length; i++) { 
        results = results.concat(r[i]); 
        for (j = 0; j < r[i].length; j++) { 
         taskUrls = taskUrls.concat(tasks[i].url); 
        } 
       } 
       results = dojo.map(results, function (result, index) { 
        var feature = result.feature; 
        var layerName = result.layerName; 
        var serviceUrl = taskUrls[index]; 
        feature.attributes.layerName = result.layerName; 

        var template = new esri.InfoTemplate("", "Service Url: " + serviceUrl + "<br/><br/>Layer name: " + result.layerName + "<br/><br/> Object Id: ${OBJECTID}"); 
        feature.setInfoTemplate(template); 

        var resultGeometry = feature.geometry; 
        var resultType = resultGeometry.type; 
        return feature; 
       }); 

       if (results.length === 0) { 
        map.infoWindow.clearFeatures(); 
       } else { 
        map.infoWindow.setFeatures(results); 
       } 
       map.infoWindow.show(idPoint); 
       return results; 
      } 

      function createIdentifyParams(layers, evt) { 
       var identifyParamsList = []; 
       identifyParamsList.length = 0; 
       dojo.forEach(layers, function (layer) { 
        var idParams = new esri.tasks.IdentifyParameters(); 
        idParams.width = map.width; 
        idParams.height = map.height; 
        idParams.geometry = evt.mapPoint; 
        idParams.mapExtent = map.extent; 
        idParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE; 
        var visLayers = layer.visibleLayers; 
        if (visLayers !== -1) { 
         var subLayers = []; 
         for (var i = 0; i < layer.layerInfos.length; i++) { 
          if (layer.layerInfos[i].subLayerIds == null) 
           subLayers.push(layer.layerInfos[i].id); 
         } 
         idParams.layerIds = subLayers; 
        } else { 
         idParams.layerIds = []; 
        } 
        idParams.tolerance = 3; 
        idParams.returnGeometry = true; 
        identifyParamsList.push(idParams); 
       }); 
       return identifyParamsList; 
      } 

     }); 
    </script> 
</head> 

<body> 
    <div id="map"></div> 
</body> 

</html> 
+0

感謝您指引我在正確的方向。我已經更新了我的代碼以顯示我的結果。彈出窗口現在看起來就像來自esri JavaScript API的附件編輯器小部件。 – Joe 2014-09-04 21:44:51