我理解在以下Javascript代码中存在某种上下文混淆。
有人可以解释我为什么遇到这个问题以及如何解决这个问题?
我有一个名为Model的类似乎工作正常。在这个类中有一个名为update()的方法。这将对后端执行AJAX调用并解析返回的JSON。这就是事情变得棘手的地方。正确的查询将发送到后端,并返回正确的JSON。但是,在解析过程中,两个模型之间存在某种冲突或上下文问题。
我通过名为View的另一个对象调用update函数。此View对象具有模型列表(Model的实例)。然后,视图将调用每个视图的每个更新功能。这很有效,直到解析返回的数据。
如评论中所述,这里是数据对象的一个示例(手动重新创建,无法弄清楚如何从控制台复制它)。请注意,此对象可能没有索引0中的所有条目(在以下情况下,它可能缺少TLM_NO)。此外,返回的行数(在这种情况下只有'0'变化)。更新功能的部分目标是检测到这一点,并在没有任何内容的情况下用“N / A”填充DOM的正确部分。
{valid: true,
0: {'TLM_NO': '00000', 'TLM_NAME': 'YYY-14 Tlm Rel 19'}}
在下面的代码中,一切都很好,直到有评论的行“/!\ HERE / !\".
this.update = function(dbi) {
console.log('Updating model ' + this.name + '.');
var modelObj = this; // This is used to have a reference to 'this' Model while in other contexts.
if (this.columns.length == 0) {
/* Let's build all the columns */
$("[id^='" + this.ref + "']").each(function() {
var colName = $(this).attr('id').split('-')[1];
if (modelObj.columns.indexOf(colName) == -1) {
modelObj.columns.push(colName);
}
});
}
/* Let's build the bindings. */
var allBindings = {};
for (placeholder in this.bindings) {
allBindings[placeholder] = this.bindings[placeholder].val();
}
$.post(path + 'inc/fetch.php', {
dbi : dbi,
table : this.table,
columns : btoa(this.columns),
limit : this.limit,
offset : this.offset,
distinct : this.distinct,
where : btoa(this.where),
bindings : btoa(JSON.stringify(allBindings))
}, function(data) {
if (!data.valid) {
$("#userError>p>span.userMessage").html(data.msg);
$("#userError").dialog({
width : 500,
buttons : {
'Dismiss' : function() {
$(this).dialog("close");
}
}
});
} else {
/* The data returned by the backend is simply JSON data with the key-value pair. There is one key per row returned. */
var numRows = 0; // /!\ HERE /!\ Starting here, displaying the data variable will always display the first of two objects.
for ( var rowID in data) {
if (rowID == 'valid')
continue;
numRows++;
for (column in data[rowID]) {
console.log('[' + modelObj.str() + '] setting #' + modelObj.ref + '-' + column + ' to [' + data[rowID][column] + ']');
var el = $('#' + modelObj.ref + '-' + column);
var val = data[rowID][column];
switch (el[0].nodeName) {
case "SELECT":
el.html('<option val="' + val + "'>" + val + "</option>");
break;
case "TD":
el.text(val);
break;
case "INPUT":
el.val(val);
break;
default:
console.log('Dont know how to display "' + val + '"!');
}
}
}
if (numRows < modelObj.columns.length) {
for ( var cNo in modelObj.columns) {
var column = modelObj.columns[cNo];
console.log("col = " + column);
console.log('data');
console.log(data);
console.log('columns');
console.log(modelObj.columns);
console.log('[0] of ' + '#' + modelObj.ref)
var par = $('#' + modelObj.ref).nodeName;
var el = $('#' + modelObj.ref + '-' + column);
var val = data[0][column];
switch (par) {
case "SELECT":
el.html('<option val="' + val + "'>" + val + "</option>");
break;
case "TABLE":
var limit = $('#' + modelObj.ref + ">tr").length - 1; // The first line (tr) is the header.
for ( var missingRow in limit) {
if (data.hasOwnProperty(missingRow) == 0 || data[missingRow].hasOwnProperty(column) == 0) {
console.log('[' + modelObj.str() + '] setting #' + modelObj.ref + '-' + column + ' to [N/A]')
$('#' + modelObj.ref + '-' + column + '-' + missingRow).text('N/A');
}
}
break;
case "INPUT":
el.val(val);
break;
default:
console.log('Dont know how to display "' + val + '"!');
}
}
}
}
}, "json");
};
任何想法都有帮助。提前谢谢。
答案 0 :(得分:0)
通过声明范围顶部的所有变量,我希望它们被定义,并通过以更结构化的方式重新排列返回的JSON数据(参见下面的粘贴),我能够解决问题。
供参考,这是JSON数据。
{"items":[{"TLM_NO":"0000000","TLM_NAME":"NSS-14 Tlm Rel 19"}],"valid":true}
这是更新的update
方法。
this.update = function(dbi) {
var modelObj = this/* This is used to have a reference to 'this' Model while in other contexts. */;
var allBindings = {} /* Used to relate binding to their values */;
console.log('Updating model ' + this.name + '.');
if (this.columns.length == 0) {
/* Let's build all the columns */
$("[id^='" + this.ref + "-']").each(function() {
var colName = $(this).attr('id').split('-')[1];
if (modelObj.columns.indexOf(colName) == -1) {
modelObj.columns.push(colName);
}
});
}
/* Let's build the bindings. */
for ( var placeholder in this.bindings) {
allBindings[placeholder] = this.bindings[placeholder].val();
}
$.post(path + 'inc/fetch.php', {
dbi : dbi,
table : this.table,
columns : btoa(this.columns),
limit : this.limit,
offset : this.offset,
distinct : this.distinct,
where : btoa(this.where),
bindings : btoa(JSON.stringify(allBindings))
}, function(data) {
var numRows = 0 /* Used to parse data. */;
var el /* Will store the element where to set the */;
var val /* will store the current value returned in JSON. */;
var par /* will store the parent element of 'el'. */;
var updateRows = true; /* This is used to count the rows. We only have to count them once. */
if (!data.valid) {
$("#userError>p>span.userMessage").html(data.msg);
$("#userError").dialog({
width : 500,
buttons : {
'Dismiss' : function() {
$(this).dialog("close");
}
}
});
return;
} else {
/* The data returned by the backend is simply JSON data with the key-value pair. There is one key per row returned. */
for ( var rowID in data.items) {
for ( var cur_Column in data.items[rowID]) {
if (updateRows)
numRows++;
console.log('[' + modelObj.str() + '] setting #' + modelObj.ref + '-' + cur_Column + ' to [' + data.items[rowID][cur_Column] + ']');
el = $('#' + modelObj.ref + '-' + cur_Column);
val = data.items[rowID][cur_Column];
switch (el[0].nodeName) {
case "SELECT":
el.append('<option value="' + val + '">' + val + "</option>");
break;
case "TD":
el.text(val);
break;
case "INPUT":
el.val(val);
break;
default:
console.log('Dont know how to display "' + val + '"!');
}
}
updateRows = false;
}
if (numRows < modelObj.columns.length) {
for ( var cNo in modelObj.columns) {
var curColumnCorr = modelObj.columns[cNo];
par = $('#' + modelObj.ref)[0].nodeName; // TODO add model name to whatever parent there is.
el = $('#' + modelObj.ref + '-' + curColumnCorr);
switch (par) {
case "TABLE":
for ( var missingRow = 1; missingRow <= modelObj.limit; missingRow++) {
if (data.items.hasOwnProperty(missingRow) == 0 || data.items[missingRow].hasOwnProperty(curColumnCorr) == 0) {
console.log('[' + modelObj.str() + '] setting ' + '#' + modelObj.ref + '-' + curColumnCorr + '-' + missingRow + ' to [N/A]');
$('#' + modelObj.ref + '-' + curColumnCorr + '-' + missingRow).text('N/A');
} else {
console.log(data.items);
}
}
break;
default:
console.log('WARNING: Implementation of filling in values for a ' + par + ' parent is pending.');
}
}
}
}
}, "json");
};