我有一个带有四个函数的模块,它们一个接一个地调用。我正在尝试遵循Revealing Module Pattern。其中一个功能是公共的,其余的是私人的。它是这样的:
publicMethod
从queryNames
publicMethod
从execute(parameters, callback?, errback?)
queryNames
addNamesList
被称为callback?
execute
参数
dijit/form/CheckBox
,并触发方法querySegments
onChange
querySegments
需要调用publicMethod
中创建的对象的方法。问题出在第6步,我无法访问步骤1中创建的对象。
我尝试在步骤3中使用dojo hitch来定义callback?
参数,但我无法使其工作。我尝试将this
放在第一个参数中,但即使这样,我也无法达到调用addNamesList
所需的范围。
以下是一些用于演示此问题的代码。
define([
'dojo/dom',
'dijit/form/CheckBox',
'esri/layers/ArcGISDynamicMapServiceLayer',
'esri/tasks/query',
'esri/tasks/QueryTask',
'dojo/_base/lang'
],
function (
dom,
CheckBox,
ArcGISDynamicMapServiceLayer,
Query, QueryTask,
lang
) {
// ***************
// private methods
// ***************
// fetch names and call addNamesList to put the list in place
var queryNames = function (map, mapLayer) {
// new QueryTask(url, options?)
var queryTask = new QueryTask("url")
var query = new Query()
// execute(parameters, callback?, errback?)
// this callback passes an argument called featureSet
queryTask.execute(query, lang.hitch(map, "addNamesList", mapLayer), function(error) {console.log(error)})
}
// callback function of queryNames
var addNamesList = function (mapLayer, featureSet) {
console.log('addOplist')
var namesCount = featureSet.features.length
for (var i = 0; i <namesCount; i++) {
// work
var cbox = new CheckBox({
id: "cbox_" + i,
value: featureSet.features[i].attributes["someID"],
checked: false,
onChange: function (evt) {
querySegments(this.value, mapLayer)
}
})
cbox.placeAt("someDiv" + i, "first")
}
}
// triggered by the checkbox event
var querySegments = function (name, mapLayer) {
// build the query
var queryStatement = "someID = " + name
var layerDefinitions = [queryStatement]
// call a method of mapLayer
mapLayer.setLayerDefinitions(layerDefinitions)
}
// **************
// public methods
// **************
var publicMethod = function (map) {
var mapLayer = new ArcGISDynamicMapServiceLayer('restURL')
map.addLayer(mapServiceLayer)
queryNames(map, mapLayer)
return mapLayer
}
return {
publicMethod: publicMethod
}
}
)
您可以在this other (and more broad) question上看到更详细的解释和工作示例,我已将其放在代码审核中。
我是JavaScript的新手,我想我仍然有很多关于范围,闭包和回调的问题。
我将非常感谢任何意见,包括如何改进这个问题。
使用此当前实现(使用dojo hitch),不会引发任何错误。方法addNamesList
未被调用(也不是errback
,我也不明白为什么)。我认为这是因为addNamesList
不在map
&#39; s(hitch first argument)命名空间。我试图改为this
,但没有区别。
在我决定使用hitch之前,代码看起来像这样:
var queryNames = function (map, mapLayer) {
...
queryTask.execute(query, addNamesList)
}
var addNamesList = function (featureSet) {
...
...
...
querySegments(this.value, mapLayer)
}
但是我无法在复选框事件触发的方法中达到mapLayer
。它会抛出Uncaught ReferenceError: mapLayer is not defined
。这就是我试图使用故障的原因。
答案 0 :(得分:3)
Javascript是异步的,因此来自db,http请求或通过回调返回的任何数据都非常多。以下是代码中发生的情况:
addNamesList
的{{1}}并且不返回任何内容map
addNamesList
在背景中仍有一些东西仍然没有被触及因此,为避免这种情况,您应该通过回调从公共方法返回数据,因此您将mapLayer
作为第二个参数传递给public方法,然后传递给querySegments。然后,在callback
的成功回调中,当你最终得到结果时,你会这样做:
query
所以,你应该做的就是将callback(mapLayer);
尽可能深地传递到你已准备好callback
的地方(所以你已经完成了你想要的一切),然后执行mapLayer
。
此致,亚历山大