繁体   English   中英

了解Javascript模块和插件中的复杂范围

[英]Understanding Complex Scope in Javascript Modules and Plugins

我知道Stack上有很多关于JS Scope的问题...但是我遇到了一个无法解决的具体问题。 我有一个看起来像这样的Javascript模块(尽管已大大简化):

module.exports = {
  $company: $('#id_company'),
  $companyCtrl: null,
  $jobType: $('#id_job_type'),
  $jobTypeCtrl: null,

  init: function() {
    var _this = this;
    this.$companyCtrl = this.$company.selectize({
      onChange: function(value) {
        _this.companyChanged(value);
      }
    })[0].selectize;
  },

  companyChanged: function() {
    // Company changed has been fired and does a few things
    // before it calls this:
    this.updateJobType();
  },

  updateJobType: function() {
    var _this = this;
    $.ajax({
      url:'/ajax-url',
      data: {
        'id': this.companyID
      }
    })
    .done(function(data) {
      // If our job type selectize() instance hasn't been setup,
      // then create it now
      if (_this.$jobTypeCtrl === null) {
        // ------------
        // PROBLEM BLOCK 
        _this.$jobTypeCtrl = _this.$jobType.selectize({
          onChange: function(value) {
            if (_this.currentModel !== 'wire_add') {
              _this.jobTypeChanged(value);
            }
          }
        })[0].selectize;
        // ------------
      }

      // Reload and re-enable input
      _this.$jobTypeCtrl.reloadFromOriginalInput();
      _this.$jobTypeCtrl.enable();
    });
  },
}

现在,这就是我不了解的东西,如果我将“ PROBLEM BLOCK”移到Ajax调用之外,然后将其放回init(),则可以正常工作。 但是,据我所知,在当前位置范围 (_this = this)与init函数中的范围 完全相同

更具体地说,我遇到的问题是,当代码在Ajax处理程序内部时,“ onChange”处理程序永远不会触发, 但是插件实例仍会创建并按其他方式运行 但是,如果我将其移至init(),则会触发onChange处理程序,而无需对代码进行任何其他更改

我们将不胜感激任何帮助,以帮助我包扎一切。 谢谢!

我有一个类似的问题,您开始使用对象追逐自己的尾巴。

使用模块的力量在于它们具有自己的上下文。 因此,一旦编译完成,文件便知道其中包含哪些var和funcs。 一旦涉及异步回调,就不需要跟踪各个函数之间的this反弹,这将成为一场噩梦。

我建议用顶部和函数的vars重写模块,因此调用任何函数都更容易,而无需尝试从此处,任何地方和任何地方传递正确的_this/self上下文。

这是未经测试的重写:

module.exports = {
  var $company = $('#id_company'),
      $companyCtrl = null,
      $jobType = $('#id_job_type'),
      $jobTypeCtrl = null;

function init() {
    $companyCtrl = $company.selectize({
      onChange: function(value) {
        companyChanged(value); // <== invoke any function and treat them as black-box code
      }
    })[0].selectize;
}

function companyChanged() {
    // Company changed has been fired and does a few things
    // before it calls this:
    updateJobType();
}

function updateJobType() {
    $.ajax({
      url:'/ajax-url',
      data: {
        'id': companyID
      }
    })
    .done(function(data) {
      // If our job type selectize() instance hasn't been setup,
      // then create it now
      if ($jobTypeCtrl === null) {
        // ------------
        // PROBLEM BLOCK 
        $jobTypeCtrl = $jobType.selectize({
          onChange: function(value) {
            if (currentModel !== 'wire_add') {
              jobTypeChanged(value);
            }
          }
        })[0].selectize;
        // ------------
      }

      // Reload and re-enable input
      $jobTypeCtrl.reloadFromOriginalInput();
      $jobTypeCtrl.enable();
    });
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM