我试图在动态地图服务层上使用识别工具,并显示一个信息窗口,显示附加到记录的图像。我得瞎折腾才能得到特征层,但这是可行的。我对延期付款有意见。
问题在这里:标识任务返回一个dojo延迟对象。我有一个回调,当延迟被解决时运行。在这个回调函数中,我运行另一个名为queryattachmentinfo的函数。当它运行时,"return feature"行将在queryattachmentinfo函数之前触发。我不知道为什么。回调中的所有内容不应该同步发生吗?如何让回调函数等待queryAttachmentInfo完成?我使用setTimeout来强制脚本等待一秒钟,这有时有效,但我知道这不是一个好的解决方案。
欢迎任何帮助。
下面的代码…function executeIdentifyTask(evt) {
identifyParams.geometry = evt.mapPoint;
identifyParams.mapExtent = map.extent;
var deferred = identifyTask.execute(identifyParams);
deferred.addCallback(function(response) {
return dojo.map(response, function(result) {
var feature = result.feature;
var fLayerPath = "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0"
var featureLayer = new esri.layers.FeatureLayer(fLayerPath);
var objID = feature.attributes.OBJECTID;
feature.attributes.layerName = result.layerName;
//alert(result.layerId);
if(result.layerName === 'Tax Parcels'){
featureLayer.queryAttachmentInfos(6737858, function (infos) {
if (infos.length>0) {
el = document.createElement('img');
el.setAttribute('src', infos[0].url);
t = document.createElement('table');
//first row Request Type
r = t.insertRow(0);
r.bgColor="#00FFFF";
c = r.insertCell(0);
c1 = r.insertCell(1);
c.innerHTML="Request Type";
c1.innerHTML=feature.attributes.building;
//second row District
r1 = t.insertRow(-1);
c2 = r1.insertCell(0);
c2_1 = r1.insertCell(1);
c2.innerHTML="District";
c2_1.innerHTML=feature.attributes.UNIT;
//third row Status
r2 = t.insertRow(-1);
r2.bgColor="#00FFFF";
c3 = r2.insertCell(0);
c3_1 = r2.insertCell(1);
c3.innerHTML="Status";
c3_1.innerHTML=feature.attributes.PARCELID ;
var len = infos.length;
for (var i = 0; i < len;i++)
{
newRow = t.insertRow(-1);
newCell = newRow.insertCell(0);
newCell.colSpan=2;
newCell.innerHTML="<a href="+infos[i].url+"/><img src="+infos[i].url+"/>";
//els[i]= document.createElement('img');
//els[i].setAttribute('src', infos[i].url);
//alert(infos[i].url);
}
var template = new esri.InfoTemplate("", t);
feature.setInfoTemplate(template);
//return feature;
}
else
{
var template = new esri.InfoTemplate("", "${Postal Address} <br/> Different: ${First Owner Name}");
feature.setInfoTemplate(template);
//eturn feature;
}
});
console.log(feature.attributes.PARCELID);
}
else if (result.layerName === 'Building Footprints'){
var template = new esri.InfoTemplate("", "Parcel ID: ${PARCELID}");
feature.setInfoTemplate(template);
//return feature;
}
return feature;
});
});
setTimeout(function(){map.infoWindow.setFeatures([ deferred ])},1000);
map.infoWindow.show(evt.mapPoint);
}
问题似乎是featureLayer.queryAttachmentInfos()
本身是异步的,因此,在'Tax parcel '的情况下,map.infoWindow.setFeatures()
和map.infoWindow.show()
只能在异步活动完成时调用。
同时,在'Building Footprints'的情况下,map.infoWindow.setFeatures()
和map.infoWindow.show(evt.mapPoint)
可以被同步调用(在外部异步回调中)。
这意味着有一小段代码应该从两个地方调用。您可以重复几行代码或编写一个worker函数,如下所示:
var showInfoWindow = function(feature, tpl) {
// A utility function which creates and populates an infowindow
// and shows it at evt.mapPoint
feature.setInfoTemplate( new esri.InfoTemplate("", tpl) );
map.infoWindow.setFeatures(feature);
map.infoWindow.show(evt.mapPoint);
}
这是在上下文中(为了清晰起见,删除了所有笨重的DOM构建):
function executeIdentifyTask(evt) {
identifyParams.geometry = evt.mapPoint;
identifyParams.mapExtent = map.extent;
var showInfoWindow = function(feature, tpl) {
// A utility function which creates and populates an infowindow
// and shows it at evt.mapPoint
feature.setInfoTemplate( new esri.InfoTemplate("", tpl) );
map.infoWindow.setFeatures(feature);
map.infoWindow.show(evt.mapPoint);
}
var deferred = identifyTask.execute(identifyParams);
deferred.addCallback(function(response) {
return dojo.map(response, function(result) {
var feature = result.feature;
//var objID = feature.attributes.OBJECTID;//???
feature.attributes.layerName = result.layerName;
if(result.layerName === 'Tax Parcels') {
var fLayerPath = "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0";
var featureLayer = new esri.layers.FeatureLayer(fLayerPath);
featureLayer.queryAttachmentInfos(6737858, function(infos) {
var t, tpl;
if(infos.length > 0) {
t = document.createElement('table');
//***** Reinsert several lines of code here *****
//***** Remember to localize variables with `var` *****
tpl = t;
}
else {
tpl = "${Postal Address} <br/> Different: ${First Owner Name}";
}
showInfoWindow(feature, tpl);//<<<<< create, populate and display an infowindow
});
}
else if (result.layerName === 'Building Footprints') {
showInfoWindow(feature, "Parcel ID: ${PARCELID}");//<<<<< create, populate and display an infowindow
}
//return feature;//???
});
});
}
我所做的一切都是在没有任何dojo或arcgis的特殊知识的情况下进行洗牌。除非我出错,所有都应该工作。也就是说,我只能测试语法错误,因此请准备好进行一些调试。请记住将构建表格的粗行粘贴回。
我试了试代码,但没能让它工作。它看起来应该可以工作,或者至少应该在地图上显示一个信息窗口。遍历它,填充了显示窗口所需的所有对象。不知道为什么不能....
如果我在第一个帖子中没有说清楚,我很抱歉。一个问题是,识别任务可以(通常也确实)返回一个特征数组。在我看来,"map.infoWindow.setFeatures([deferred]);"行在queryAttachmentInfo触发之前触发。我有一个愚蠢的解决方法,我使用一个窗口。setTimeout函数等待一秒钟,但这并不能保证所有的queryattachmentinfo都将被解析。