我这里有一个代码,它会在数据库中插入数据,如果数据已经存在,它将首先过滤,并询问用户是否要继续使用bootstrap模式插入数据。现在的问题是它只在循环结束时显示,我想要的是每次在数据库中找到数据时弹出模式都会显示。
$.each(person, function(index, value){
var existing = DisticntVal(value);
if(existing == 0){
InsertPerson(value);
}else{
var a = ConfirmYesNo(value['person'] + " already exist. Do you want to continue?");
a.then(function (b) {
if(b == 1){
InsertPerson(value);
}
});
}
});
function ConfirmYesNo(msg) {
var dfd = jQuery.Deferred();
var $confirm = $('#exampleModal');
$confirm.modal('show');
$('#message').html(msg);
$('#btnyes').off('click').click(function () {
$confirm.modal('hide');
dfd.resolve(1);
return 1;
});
$('#btnno').off('click').click(function () {
$confirm.modal('hide');
return 0;
});
return dfd.promise();
}
function DisticntVal(person) {
var returncount;
var nperson = JSON.stringify(person);
$.ajax({
url: 'chckdistinct.php',
type: 'post',
data: {person: nperson},
async: false,
success: function(response) {
returncount = response;
},
error: function(xhr, desc, err) {
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
}
});
return returncount;
}
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p id="message"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" id="btnno">No</button>
<button type="button" class="btn btn-primary" id="btnyes">Yes</button>
</div>
</div>
</div>
</div>
需要帮助。
答案 0 :(得分:0)
主要问题是你的ConfirmYesNo
函数不会暂停循环的执行。它只是让HTML(模态)的那一点可见,然后继续。因此,在您的用户有机会响应模态之前,循环会一次又一次地继续,但几乎立即用下一组内容覆盖模态内容和事件处理程序,直到它结束。这就是为什么你似乎只看到最后一项。其他项目会显示出来,但是它们会被快速覆盖,您实际上不太可能看到它们,而旧的承诺永远不会被解决。
另一条建议:async: false
是一个坏主意。它会导致糟糕的用户体验(浏览器在ajax请求期间被锁定,并且无法点击任何内容)并且也已被弃用,因此浏览器可能会在将来删除该功能。
这是一个完全基于promises的替代解决方案,完全避免使用循环。我已稍微修改它以使其在此片段中可运行,但我留下了原始代码中我无法使用注释掉的部分,以便您可以看到恢复它们的位置。我还必须猜测你的人物对象的结构,所以你可能需要改变它以适应你的真实数据。
var people = [{
"id": 1,
"name": "A"
}, {
"id": 2,
"name": "B"
}, {
"id": 3,
"name": "C"
},
{
"id": 4,
"name": "D"
}
];
$(function() {
$("#begin").click(processInserts);
});
function processInserts() {
processIndividualInsert(0);
}
function processIndividualInsert(index) {
if (index < people.length) {
var person = people[index];
return distinctVal(person).then(function(existing) {
if (existing == 0) {
console.log(person.name + " doesn't exist");
insertPerson(person);
return processIndividualInsert(index + 1);
} else {
return ConfirmYesNo(person.name + " already exists. Do you want to continue?").then(function(b) {
if (b == 1) {
console.log(person.name + " already exists. User opted to continue with the insert anyway");
insertPerson(person);
return processIndividualInsert(index + 1);
} else {
console.log(person.name + " already exists. User opted not to continue with the insert");
return processIndividualInsert(index + 1);
}
});
}
});
} else {
console.log("All completed");
return false;
}
}
function distinctVal(person) {
//generate arbitrary dummy response data:
var response = 0;
if (person.id % 2 == 0) response = 1;
//dummy promise for testing:
var prom = $.Deferred();
prom.resolve(response);
return prom.promise();
//this would be your real code instead of the dummy code:
/*
return $.ajax({
url: 'chckdistinct.php',
type: 'post',
data: {
person: JSON.stringify(person);
},
error: function(xhr, desc, err) {
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
}
});*/
}
function ConfirmYesNo(msg) {
var dfd = jQuery.Deferred();
//dummy code to avoid bootstrap
$('#exampleModal').show();
//your real code would be:
/*var $confirm = $('#exampleModal');
$confirm.modal('show');*/
$('#message').html(msg);
$('#btnyes').off('click').click(function() {
//dummy code to avoid bootstrap
$('#exampleModal').hide();
//your real code would be:
/*$confirm.modal('hide'); */
dfd.resolve(1);
});
$('#btnno').off('click').click(function() {
//dummy code to avoid bootstrap
$('#exampleModal').hide();
//your real code would be:
/*$confirm.modal('hide'); */
dfd.resolve(0);
});
return dfd.promise();
}
function insertPerson(person) {
//don't know what's supposed to go in here, but presumably another async ajax call which will insert the person data
return true;
}
&#13;
.modal {
display: none;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="begin">
Click to Begin
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
</div>
<div class="modal-body">
<p id="message"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" id="btnno">No</button>
<button type="button" class="btn btn-primary" id="btnyes">Yes</button>
</div>
</div>
</div>
</div>
&#13;