2014-09-03 6 views
1

식별 태스크의 결과를 기반으로 모든 첨부 파일을 조회하려고합니다. 레이어에 첨부 파일이있는 경우 infoTemplate의 맨 아래에 링크를 추가하고 싶습니다.중첩 된 Dojo 지연 처리 방법

다중 도우 Deferred 오브젝트를 조작하는 데 문제가 있습니다. 반환 값이 콘솔에 기록되기 때문에 해결되고 있지만 정보창은 채워지지 않습니다.

그래서 여러 개의 중첩 지연을 처리하는 적절한 방법은 무엇입니까? 지연 목록은 올바른 방향으로 나아가는 단계 인 것처럼 보이지만이 상황에서 내가 어떻게 형식화할지 확실하지 않습니다.

감사합니다,

업데이트 : 내가 아래에있는 내 작업 코드를 업데이트 한

.

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

올바른 방향으로 나를 안내해 주셔서 감사합니다. 내 결과를 보여주기 위해 위의 코드를 업데이트했습니다. popup은 이제 esri JavaScript API의 첨부 파일 편집기 위젯과 같습니다. – Joe