如何使用jquery在循环中调用bootstrap模式

时间:2017-10-10 07:34:31

标签: jquery ajax

我这里有一个代码,它会在数据库中插入数据,如果数据已经存在,它将首先过滤,并询问用户是否要继续使用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">&times;</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>

需要帮助。

1 个答案:

答案 0 :(得分:0)

主要问题是你的ConfirmYesNo函数不会暂停循环的执行。它只是让HTML(模态)的那一点可见,然后继续。因此,在您的用户有机会响应模态之前,循环会一次又一次地继续,但几乎立即用下一组内容覆盖模态内容和事件处理程序,直到它结束。这就是为什么你似乎只看到最后一项。其他项目会显示出来,但是它们会被快速覆盖,您实际上不太可能看到它们,而旧的承诺永远不会被解决。

另一条建议:async: false是一个坏主意。它会导致糟糕的用户体验(浏览器在ajax请求期间被锁定,并且无法点击任何内容)并且也已被弃用,因此浏览器可能会在将来删除该功能。

这是一个完全基于promises的替代解决方案,完全避免使用循环。我已稍微修改它以使其在此片段中可运行,但我留下了原始代码中我无法使用注释掉的部分,以便您可以看到恢复它们的位置。我还必须猜测你的人物对象的结构,所以你可能需要改变它以适应你的真实数据。

&#13;
&#13;
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;
&#13;
&#13;