微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 在回调和事件后调用方法

我有一个模块,有四个函数,一个一个调用.我正在尝试遵循Revealing Module Pattern.其中一个功能是公共的,其余的是私人的.它是这样的:

>从另一个模块调用publicmethod
>从publicmethod调用queryNames
> query(参数,回调?,错误回复?)是从queryNames调用
> addNamesList被称为回调?执行的论点
>创建了几个dijit / form / CheckBox,并在onChange上触发方法querySegments
> querySegments需要调用在publicmethod中创建的对象的方法.

问题出在第6步,我无法到达步骤1中创建的对象.

我试过用dojo hitch来定义回调?第3步中的参数,但我不能让它工作.我尝试将它放在它的第一个参数中,但即便如此,我也无法达到调用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(hitch first argument)命名空间中.我尝试用这个来代替,但没有区别.

在我决定使用hitch之前,代码看起来像这样:

var queryNames = function (map, mapLayer) {
  ...
  queryTask.execute(query, addNamesList)
}

var addNamesList = function (featureSet) {
  ...
    ...
      ...
        querySegments(this.value, mapLayer)
}

但后来我无法在复选框事件触发的方法内到达mapLayer.它会抛出Uncaught ReferenceError:mapLayer未定义.这就是我试图使用故障的原因.

解决方法:

Javascript是异步的,因此几乎所有来自db,http请求或通过回调返回的数据的数据.以下是您的代码中发生的情况:

> public方法调用queryNames
> queryNames异步调用map的addNamesList并且不返回任何内容
> public方法收回控制权,同时有些东西正在使用addNamesList
> mapLayer未经修改而返回,而某些内容仍在后台进行

因此,为避免这种情况,您应该通过回调从公共方法返回数据,因此您将回调作为第二个参数传递给public方法,然后传递给querySegments.然后,在成功回调查询时,当你最终得到结果时,你会做:

callback(mapLayer);

所以,你应该做的一切就是把这个回调尽可能深地传递到你准备好mapLayer的地方(所以你已经完成了你想要的一切),然后做一个回调(mapLayer);.

Thisthis可能会更好地解释.

此致,亚历山大

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐