Yii2表单验证失败时如何保留修改后的数据?
问题原因分析
你的核心问题出在两个地方:
- 表单字段硬编码了
value属性为数据库中$user的原始值,无论用户提交了什么新内容,页面刷新时都会强制覆盖为数据库值。 - 控制器中没有将数据库用户数据预先填充到表单模型
$model中,导致验证失败时,$model无法保留用户提交的输入值。
解决方案
1. 修改控制器代码
先从数据库获取用户数据,将其填充到$model作为初始值;提交请求时,load()方法会自动用POST数据覆盖$model中的值,验证失败时$model会保留用户输入的内容。
$rowId = \Yii::$app->getRequest()->getQueryParam('rowId'); $user = User::findOne(['id' => $rowId]); $model = new UserForm(); // 将数据库用户数据填充到表单模型,作为初始值 $model->userTitleId = $user->user_title_id; $model->userFirstname = $user->user_firstname; // 其他字段同理赋值 if ($model->load(\Yii::$app->request->post())) { if($model->editUser()) { return $this->redirect(['/user/user']); } } $optionTitleList = ArrayHelper::map(OptionsTitle::find()->all(), 'id', 'description'); return $this->render('/user/user/edit-user', [ 'model' => $model, 'optionTitleList' => $optionTitleList, ]);
如果字段较多,可在UserForm类中添加批量赋值方法优化代码:
// 在UserForm类中新增方法 public function loadUser(User $user) { $this->userTitleId = $user->user_title_id; $this->userFirstname = $user->user_firstname; // 其他字段依次添加 }
然后控制器中替换为:
$model->loadUser($user);
2. 修改表单代码
移除硬编码的value属性,Yii的ActiveForm会自动从$model读取对应字段的值——初始时是数据库原始值,验证失败时是用户提交的输入值。
<div class="col-sm-9"> <?= $form->field($model, 'userTitleId')->dropDownList( $optionTitleList, ['class' => 'form-select form-select-sm border-primary'] )->label(false) ?> </div> <div class="col-sm-9"> <?= $form->field($model, 'userFirstname')->textInput( ['placeholder' => 'Enter first name', 'class' => 'form-control form-control-sm border-primary', 'maxlength' => '40'])->label(false) ?> </div>
原理说明
修改后流程变为:
- 页面首次加载:
$model被填充数据库用户数据,表单从$model读取值显示原始内容。 - 用户提交表单:
load()方法将POST数据写入$model,若验证失败,$model保留用户输入的内容,表单渲染时直接读取这些内容,同时显示验证错误提示。
内容的提问来源于stack exchange,提问作者Quentinb
相关产品推荐
相关产品推荐

