我已经使用jQuery几年了,对vanilla javascript的理解非常有限。范围,对象模型,以及我在javascript中看到的许多设计模式让我感到困惑。我正在尝试实现一个最终将用于我需要编写的调度插件的类,并且我很难理解为什么存储在我的一个类成员中的数据似乎不可用。我不确定问题是否与范围或其他一些我不理解的行为有关。
我在相应位置的评论中有以下代码和2个问题。第一个问题是我的getJSON调用中的范围变通方法是否是在getJSON中处理范围问题的正确方法。我的第二个问题是为什么我不能直接访问schedule.data。
function Schedule() {
this.year = null;
this.month = null;
this.day = null;
this.start_datetime = null;
this.start_timestamp = null;
this.end_datetime = null;
this.end_timestamp = null;
this.data = [];
return this;
}
Schedule.prototype.init = function() {
var url = '/tripsys/new_admin/employee_schedule/get_employee_schedule_data/' + this.start_timestamp + '/' + this.end_timestamp;
var self = this; // 1. trying to work around scope issues. Is this the correct way to handle the scope problems here?
$.getJSON(url, function(data) {
self.data = data;
});
}
var schedule = new Schedule();
$(document).ready(function() {
schedule.year = $('#year').text();
schedule.month = $('#month').text();
schedule.day = $('#day').text();
schedule.start_datetime = new Date(schedule.year, schedule.month - 1, schedule.day);
schedule.start_timestamp = Math.round(schedule.start_datetime.getTime() / 1000);
schedule.end_datetime = new Date(schedule.year, schedule.month - 1, schedule.day, 23, 59, 59);
schedule.end_timestamp = Math.round(schedule.end_datetime.getTime() / 1000);
schedule.init();
console.log(schedule); // if I log the whole schedule object the data that I expect to be in the "data" member is there
console.log(schedule.data); // 2. why is the data that I expect to be in the "data" member not there when I access schedule.data directly?
});
感谢您的见解。
答案 0 :(得分:1)
这可能是因为在这一行schedule.init();
中,当你执行console.log(schedule.data);
时,它会进行一个尚未完成的ajax调用。 Ajax调用是异步的。调用它们只会启动网络操作,然后立即返回。在调用成功处理函数之前,它们不会完成(并且在分配self.data
时)。
因此,如果要查看在.init()
函数中获取的调度对象的数据,则必须等到该ajax调用完成或对完成函数中的数据执行某些操作。
答案 1 :(得分:1)
第一点是正确的,因为你需要保存this
引用,因为当jQuery调用内部函数时,函数内的this
将引用ajax对象
在第二条评论中,您在ajax请求完成之前记录schedule.data
。您在登录schedule.data
时可以看到schedule
,因为当您在Google Chrome中记录对象时,手动"展开"后会检索对象属性。 chrome控制台中的对象。当您手动"展开"它,当时请求已经完成。
您可以像这样重现:
var a = {};
console.log(a); //do not "expand" the object properties yet
console.log(a.property); //undefined
a.property = "value";
//"expand" the already logged object and it will have "value"
答案 2 :(得分:1)
是的,虽然它不是范围问题,但它使用变量范围来解决上下文问题。
要访问schedule.data
,您需要等到数据到达。换句话说,将console.log
代码放在回调中。
答案 3 :(得分:1)
问题是在记录对象之前没有返回ajax调用。如果要使ajax调用同步并且init
函数在记录之前获得结果,请在ajax jQuery调用上使用async
参数:
$.ajax({
url: url,
dataType: 'json',
async: false,
success: function(data){
self.data = data;
console.log(data);
}
});