[英]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.