在回调和事件之后调用方法
Call a method after a callback and an event
我有一个包含四个函数的模块,它们一个接一个地调用。我正在尝试遵循 Revealing Module Pattern。其中一个函数是public,其余都是私有的。它是这样的:
publicMethod
被另一个模块调用
queryNames
从 publicMethod
调用
execute(parameters, callback?, errback?)
从 queryNames
调用
addNamesList
被称为 execute
的 callback?
参数
- 创建了多个
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 上看到更详细的解释和工作示例,我已将其放在 Code Review 中。
我是 JavaScript 的新手,我想我在范围界定、闭包和回调方面仍然存在很多问题。
我将非常感谢任何意见,包括如何改进这个问题。
编辑
使用当前的实现(使用 dojo hitch),不会抛出任何错误。方法 addNamesList
没有被调用(也没有调用 errback
,我也不明白为什么)。我认为这是因为 addNamesList
不在 map
的(第一个参数)命名空间中。我试着用 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
。这就是我尝试使用挂钩的原因。
Javascript 是异步的,因此几乎所有数据都来自数据库、http 请求或通过 回调 编辑的任何内容。以下是您的代码中发生的情况:
- public 方法调用 queryNames
- queryNames 异步调用
map
的 addNamesList
,并且 return 什么都没有
- public 方法收回控制权,同时
addNamesList
正在处理一些事情
mapLayer
return 未受影响,但某些内容仍在后台运行
所以,为了避免这种情况,你应该通过回调从 public 方法中 return 数据,所以你将 callback
作为第二个参数传递给 public 方法,然后到querySegments。然后,在 query
的成功回调中,当你最终准备好结果时,你做:
callback(mapLayer);
因此,您应该做的就是将此 callback
尽可能深地传递到您准备好 mapLayer
的地方(因此您已经完成了您想要的一切),然后做一个 callback(mapLayer);
.
This and this 可能会解释得更好。
最好的问候,亚历山大
我有一个包含四个函数的模块,它们一个接一个地调用。我正在尝试遵循 Revealing Module Pattern。其中一个函数是public,其余都是私有的。它是这样的:
publicMethod
被另一个模块调用queryNames
从publicMethod
调用
execute(parameters, callback?, errback?)
从queryNames
调用
addNamesList
被称为execute
的 - 创建了多个
dijit/form/CheckBox
并触发了方法querySegments
onChange
querySegments
需要调用在publicMethod
. 中创建的对象的方法
callback?
参数
问题出在第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 上看到更详细的解释和工作示例,我已将其放在 Code Review 中。
我是 JavaScript 的新手,我想我在范围界定、闭包和回调方面仍然存在很多问题。
我将非常感谢任何意见,包括如何改进这个问题。
编辑
使用当前的实现(使用 dojo hitch),不会抛出任何错误。方法 addNamesList
没有被调用(也没有调用 errback
,我也不明白为什么)。我认为这是因为 addNamesList
不在 map
的(第一个参数)命名空间中。我试着用 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
。这就是我尝试使用挂钩的原因。
Javascript 是异步的,因此几乎所有数据都来自数据库、http 请求或通过 回调 编辑的任何内容。以下是您的代码中发生的情况:
- public 方法调用 queryNames
- queryNames 异步调用
map
的addNamesList
,并且 return 什么都没有 - public 方法收回控制权,同时
addNamesList
正在处理一些事情
mapLayer
return 未受影响,但某些内容仍在后台运行
所以,为了避免这种情况,你应该通过回调从 public 方法中 return 数据,所以你将 callback
作为第二个参数传递给 public 方法,然后到querySegments。然后,在 query
的成功回调中,当你最终准备好结果时,你做:
callback(mapLayer);
因此,您应该做的就是将此 callback
尽可能深地传递到您准备好 mapLayer
的地方(因此您已经完成了您想要的一切),然后做一个 callback(mapLayer);
.
This and this 可能会解释得更好。
最好的问候,亚历山大