Inside a (dynamically generated) table I search for and find the column named "VATNumber" and iterate over all (non-header) cells of that column, using the value (vat number) as a parameter to an ajax call.
在(动态生成的)表中,我搜索并找到名为“VATNumber”的列,并使用值(桶号)作为ajax调用的参数,迭代该列的所有(非标题)单元格。
The table and button:
表格和按钮:
<table id="ResultData">
<tbody>
<tr>
<th>ID</th><th>Amount</th><th>VATNumber</th><th>Country</th>
</tr><tr>
<td>1</td><td>10000.00</td><td>DE123456789</td><td>BE</td>
</tr><tr>
<td>2</td><td>20000.00</td><td>NL000123456B01</td><td>BE</td>
</tr><tr>
<td>3</td><td>30000.00</td><td>NL001234567B01</td><td>BE</td>
</tr><tr>
<td>4</td><td>40000.00</td><td>NL002345678B01</td><td>BE</td>
</tr>
</tbody>
</table>
<p>
<button id="btnVIESCheck">CHECK</button>
</p>
This is more or less what the code looks like with (icky) synchronous ajax (contradiction in terms)
这或多或少是代码与(icky)同步ajax(术语中的矛盾)的样子
$('#btnVIESCheck').on('click', function (e) {
e.preventDefault();
var columnIndex = $('#ResultData th:contains("VATNumber")').index();
$('#ResultData tr:gt(0) td:nth-child(' + (columnIndex + 1) + ')')
.each(function () {
$this = $(this);
var vatnr = $this.text(),
rowIndex = $this.closest('tr').index();
//add ajaxloader
$this.html($this.html() + ' ' + ajaxloader);
var resultCode = checkVATNr(vatnr),
img = '';
switch (resultCode) {
case '1':
img = '<img src="Img/ok.jpg" />';
break;
case '2':
img = '<img src="Img/notok.jpg" />';
break;
case '3':
img = '<img src="Img/warning.jpg" />';
break;
default:
break;
}
$this.html(vatnr + ' ' + img);
});
});
function checkVATNr(vatnr) {
var result = '';
$.ajax({
type: "POST",
async: false,
url: 'MyWebService.asmx/CheckVATNumber',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: JSON.stringify({
'vatnr': vatnr
}),
success: function (msg) {
var xml = $.parseXML(msg.d);
$xml = $(xml);
result = $xml.find('ResultCode').text();
},
error: function (e) {
console.log("Error " + e.error);
}
});
return result;
}
Of course
- this shows the images when ALL the calls are done. Not preferable, the table might be very large
- I'd like to use proper async ajax inside the .each(), but then sometimes the results are garbled, out of order, replacing the wrong table cells and sometimes it only works for the last cell.
这显示了所有呼叫完成后的图像。不太可取,桌子可能非常大
我想在.each()中使用正确的异步ajax,但有时结果是乱码,乱序,替换错误的表格单元格,有时它只适用于最后一个单元格。
How can I write this using promises?
我怎么用承诺写这个?
1 个解决方案
#1
2
One problem is the use of global variable $this
in the each loop, which will result in $this
being always referring to the last td
element. So use define it as a local variable like var $this = $(this);
一个问题是在每个循环中使用全局变量$ this,这将导致$ this始终引用最后一个td元素。因此,使用将其定义为局部变量,如var $ this = $(this);
That is because of the use of async:false
, which blocks the browser thread from doing anything till all the ajax requests are finished.
这是因为使用了async:false,它阻止浏览器线程执行任何操作,直到完成所有ajax请求。
Use callback mechanism to process the requests like
使用回调机制来处理请求
$('#btnVIESCheck').on('click', function (e) {
e.preventDefault();
var columnIndex = $('#ResultData th:contains("VATNumber")').index();
$('#ResultData tr:gt(0) td:nth-child(' + (columnIndex + 1) + ')')
.each(function () {
var $this = $(this);
var vatnr = $this.text(),
rowIndex = $this.closest('tr').index();
//add ajaxloader
$this.html($this.html() + ' ' + ajaxloader);
checkVATNr(vatnr, function (resultCode) {
var img = '';
switch (resultCode) {
case '1':
img = '<img src="Img/ok.jpg" />';
break;
case '2':
img = '<img src="Img/notok.jpg" />';
break;
case '3':
img = '<img src="Img/warning.jpg" />';
break;
default:
break;
}
$this.html(vatnr + ' ' + img);
})
});
});
function checkVATNr(vatnr, callback) {
$.ajax({
type: "POST",
url: 'MyWebService.asmx/CheckVATNumber',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: JSON.stringify({
'vatnr': vatnr
}),
success: function (msg) {
var xml = $.parseXML(msg.d);
$xml = $(xml);
callback($xml.find('ResultCode').text());
},
error: function (e) {
console.log("Error " + e.error);
callback('');
}
});
}
Also see: How do I return the response from an asynchronous call?
另请参阅:如何从异步调用返回响应?
#1
2
One problem is the use of global variable $this
in the each loop, which will result in $this
being always referring to the last td
element. So use define it as a local variable like var $this = $(this);
一个问题是在每个循环中使用全局变量$ this,这将导致$ this始终引用最后一个td元素。因此,使用将其定义为局部变量,如var $ this = $(this);
That is because of the use of async:false
, which blocks the browser thread from doing anything till all the ajax requests are finished.
这是因为使用了async:false,它阻止浏览器线程执行任何操作,直到完成所有ajax请求。
Use callback mechanism to process the requests like
使用回调机制来处理请求
$('#btnVIESCheck').on('click', function (e) {
e.preventDefault();
var columnIndex = $('#ResultData th:contains("VATNumber")').index();
$('#ResultData tr:gt(0) td:nth-child(' + (columnIndex + 1) + ')')
.each(function () {
var $this = $(this);
var vatnr = $this.text(),
rowIndex = $this.closest('tr').index();
//add ajaxloader
$this.html($this.html() + ' ' + ajaxloader);
checkVATNr(vatnr, function (resultCode) {
var img = '';
switch (resultCode) {
case '1':
img = '<img src="Img/ok.jpg" />';
break;
case '2':
img = '<img src="Img/notok.jpg" />';
break;
case '3':
img = '<img src="Img/warning.jpg" />';
break;
default:
break;
}
$this.html(vatnr + ' ' + img);
})
});
});
function checkVATNr(vatnr, callback) {
$.ajax({
type: "POST",
url: 'MyWebService.asmx/CheckVATNumber',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: JSON.stringify({
'vatnr': vatnr
}),
success: function (msg) {
var xml = $.parseXML(msg.d);
$xml = $(xml);
callback($xml.find('ResultCode').text());
},
error: function (e) {
console.log("Error " + e.error);
callback('');
}
});
}
Also see: How do I return the response from an asynchronous call?
另请参阅:如何从异步调用返回响应?