You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CodeIgniter中用setInterval+Ajax自动显示Modal并更新数据?

问题

我想在时间到期时为所有用户弹出提醒弹窗,目前设置了当剩余天数、小时数、分钟数均为0时触发Modal和setInterval,但代码完全不起作用:Modal无法自动显示,必须刷新页面才可能出现,而且数据也无法更新。请问该怎么实现这个功能?

现有视图代码

<form action="<?php echo base_url(); ?>submissions/lock" id="btnexp" method="post">
  <input type="hidden" value="<?php echo $period['period_id']; ?>" name="period_id">
  <?php if($period['duration']!='0000-00-00 00:00:00'): ?>

          <?php 
              date_default_timezone_set('Asia/Manila');
              $datetime = date("Y-m-d H:i:s");


              $date1 = new DateTime($datetime);
              $date2 = new DateTime($period['duration']);
              $interval = $date1->diff($date2);
              $days = $interval->days;
              $hours = $interval->h;
              $min =  $interval->i;
              // echo $interval->format("%Y-%m-%d %H:%i:%s").'<br>';
              // shows the total amount of days (not divided into years, months and days like above)
              $interval->days; 
              $interval->h;
              $interval->i;
              if($days == 0 && $hours == 0 && $min == 0){ 
          ?>


          <script>
            $(function(){
                    
                    //function
                    setInterval(function(){
                        $.ajax({
                            type: 'POST',
                            url: '<?php echo base_url() ?>submissions/lock',
                            async:false,
                            cache: false,
                            success: function(data){
                              if (data == 0){
                              $('#myModal').modal('show');   
                              }                       
                            },
                            error: function(){
                                alert('Could not get Data from Database');
                            }
                        });
                    }, 1000);                
            });
          </script> 

                  
          <?php  } ?>
  <?php endif; ?>
</form>

现有控制器代码(Submissions/Lock)

public function lock()
{
    $this->submission_model->lock();
}

问题分析与解决方案

核心问题

  1. 服务器端判断仅执行一次:只有用户加载页面时刚好处于到期时刻,才会插入弹窗脚本;如果页面加载后时间才到期,脚本根本不会被渲染,自然无法触发。
  2. 控制器无返回值:lock方法只执行了模型逻辑,但没有输出任何响应数据,前端AJAX的success回调里data == 0的判断永远不成立,Modal不会显示。
  3. 定时器效率低下:每秒发起一次AJAX请求,会造成不必要的服务器压力。
  4. 同步AJAX阻塞浏览器:async:false会阻塞页面其他操作,影响用户体验。

修正步骤

1. 前端实时监控到期时间

把服务器端的到期时间传递给JS,前端计算距离到期的剩余时间,到点后直接触发弹窗并调用锁定接口,无需每秒轮询。

修改后的视图代码:

<form action="<?php echo base_url(); ?>submissions/lock" id="btnexp" method="post">
  <input type="hidden" value="<?php echo $period['period_id']; ?>" name="period_id">
  <?php if($period['duration']!='0000-00-00 00:00:00'): ?>
    <script>
      $(function(){
        // 获取服务器端的到期时间(转换为时间戳)
        const expiryTime = new Date("<?php echo $period['duration']; ?>").getTime();
        const now = new Date().getTime();
        const timeDiff = expiryTime - now;

        // 如果已经到期,直接弹窗
        if(timeDiff <= 0){
          showExpiryModal();
        } else {
          // 设置定时器,到期时触发
          setTimeout(() => {
            showExpiryModal();
          }, timeDiff);
        }

        function showExpiryModal(){
          // 调用锁定接口
          $.ajax({
            type: 'POST',
            url: '<?php echo base_url() ?>submissions/lock',
            cache: false,
            success: function(data){
              // 不管接口返回什么,直接弹窗(或根据返回值判断)
              $('#myModal').modal('show');
            },
            error: function(){
              alert('无法连接服务器');
            }
          });
        }
      });
    </script>
  <?php endif; ?>
</form>

2. 修改控制器返回响应数据

让lock方法执行完模型逻辑后,输出响应内容,方便前端判断:

public function lock()
{
    // 执行锁定逻辑
    $result = $this->submission_model->lock();
    
    // 根据执行结果返回数据,比如成功返回1,失败返回0
    echo $result ? 1 : 0;
    // 或者返回JSON格式
    // echo json_encode(['status' => $result ? 'success' : 'failed']);
}

3. 可选:实现全局实时提醒(针对所有用户)

如果需要让所有在线用户都能实时收到到期提醒,仅靠前端定时器不够(比如用户打开页面后,到期时间被后台修改),可以结合WebSocket或者长轮询实现,但这会增加复杂度。如果需求不严格,前端定时检查(比如每30秒一次)也可以接受,修改前端定时器为:

// 每30秒检查一次到期状态
setInterval(() => {
  $.ajax({
    type: 'GET',
    url: '<?php echo base_url() ?>submissions/check_expiry',
    data: {period_id: <?php echo $period['period_id']; ?>},
    success: function(data){
      if(data == 'expired'){
        $('#myModal').modal('show');
        // 弹窗后清除定时器,避免重复触发
        clearInterval(this);
      }
    }
  });
}, 30000);

同时新增一个check_expiry控制器方法,用于检查当前时间段是否到期:

public function check_expiry()
{
    $period_id = $this->input->get('period_id');
    $period = $this->submission_model->get_period($period_id);
    
    date_default_timezone_set('Asia/Manila');
    $now = new DateTime();
    $expiry = new DateTime($period['duration']);
    
    if($now >= $expiry){
      echo 'expired';
    } else {
      echo 'active';
    }
}

内容的提问来源于stack exchange,提问作者Coder Codes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:24:46