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

模型变量未更新:Ajax更新后getDay返回旧值问题排查

问题分析与解决方案:Ajax更新模型值后getDay返回旧值

嘿,这个问题我之前也踩过坑!核心原因其实是Yii框架中每个HTTP请求都会创建一个全新的控制器实例——也就是说,actionChangeDay和actionGetDay是两个完全独立的请求,它们对应的$this->planing_model根本不是同一个对象。

你在actionChangeDay里修改了当前请求实例的curent_day,但这个修改只存在于该请求的内存中,请求结束后控制器和模型实例就被销毁了。等你调用actionGetDay时,系统会重新初始化控制器和模型,自然拿到的还是原来的旧值。

下面给你几个可行的解决方案,按需选择:

1. 持久化修改到数据库(最常用)

如果这个值需要长期保存,或者需要在多个请求/会话中共享,直接把修改保存到数据库是最稳妥的做法:

public function actionChangeDay($new_curent_day){
    if(Yii::$app->request->isAjax){
        $this->planing_model->curent_day = $new_curent_day;
        // 新增保存操作,确保修改持久化
        if($this->planing_model->save()){
            return $this->planing_model->curent_day;
        } else {
            // 返回错误信息方便前端调试
            return json_encode([
                'error' => '保存失败',
                'errors' => $this->planing_model->errors
            ]);
        }
    }
}

⚠️ 注意:如果你的模型有验证规则,save()可能会因为验证不通过失败,所以一定要加上错误处理逻辑。

2. 用Session临时存储(适合短期会话)

如果只是需要在当前用户会话中临时保存这个值,不需要写入数据库,可以用Yii的Session组件:

// actionChangeDay 中存储值
public function actionChangeDay($new_curent_day){
    if(Yii::$app->request->isAjax){
        Yii::$app->session->set('planing_curent_day', $new_curent_day);
        return $new_curent_day;
    }
}

// actionGetDay 中读取值
public function actionGetDay(){
    if(Yii::$app->request->isAjax){
        // 优先从Session读取,没有则用模型默认值
        return Yii::$app->session->get('planing_curent_day', $this->planing_model->curent_day);
    }
}

这种方式的好处是轻量,用户关闭浏览器后Session会自动失效,适合临时状态存储。

3. 前端缓存值(减少请求)

既然是前端发起的请求,也可以在前端直接缓存更新后的值,后续调用getDay时直接用缓存,不用再发请求:

// 全局变量缓存当前day值
let currentDay = null;

function changeDay(){
    const newDay = $('.owl-item.center .slide_day').text();
    $.get('/planing/change-day', {new_curent_day: newDay}, function (data) {
        console.log(data);
        // 更新前端缓存
        currentDay = data;
    });
}

function getDay(){
    // 有缓存直接用,没有再发请求
    if(currentDay !== null){
        console.log(currentDay);
        return;
    }
    $.get('/planing/get-day', function (data) {
        console.log(data);
        currentDay = data;
    })
}

⚠️ 额外提醒:Ajax是异步的!如果你在调用changeDay()后立刻调用getDay(),可能changeDay的请求还没完成,getDay就已经发起了,这时候也会拿到旧值。可以用Promise保证顺序:

function changeDay(){
    return new Promise((resolve) => {
        const newDay = $('.owl-item.center .slide_day').text();
        $.get('/planing/change-day', {new_curent_day: newDay}, function (data) {
            console.log(data);
            resolve(data);
        });
    });
}

// 调用时确保顺序
changeDay().then(() => {
    getDay();
});

最后提个小细节:你的变量名拼写是curent_day(少了一个r),建议统一改成current_day,避免后续因为拼写错误踩坑~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:06:42