一、问题
在使用Yii框架创建的项目中,有一个弹窗,弹窗中有一个表单,表单的内容需要提交给后端的php controller文件做数据处理,进而对数据库进行一定的操作,但是操作执行完成以后,浏览器显示的内容没有改变,如果刷新页面,页面显示内容改变但是表单的内容会重复提交给controller程序进行重复处理。
二、解决措施
对于这种有表单提交动作的页面,表单提交的action处理方法一定要单独写,也就是,提交表单的时候不在当前页面进行操作,等表单提交动作操作完了,在重定向至当前页面,这样就可以实现页面表单提交以后刷新也不会出现重复提交的问题了。
三、具体内容
1、前端表单的设置:
<div class="modal-dialog" role="document" id="transferModal">
<?php $form = ActiveForm::begin([
'action' => 'materialtransfer',
'method'=>'post',
'options'=>['enctype' => 'multipart/form-data'],
]) ?>
<div class="modal-content" >
<div class="modal-header">
<h4 class="modal-title" style="font-weight: 700">货位转移</h4>
</div>
<div class="modal-body">
<!-- 使用一个栅栏布局进行展示和选择-->
<div style="font-weight:700;margin: 0 auto">当前货位信息:</div>
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<?= $form->field($transfer, 'company')->input('text', ['style' => 'width:100%','readonly'=>true]);?>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<?= $form->field($transfer, 'factory')->input('text', ['style' => 'width:100%','readonly'=>true]);?>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary" id="remarkSub">提交</button>
</div>
</div><!-- /.modal-content -->
<?php ActiveForm::end() ?>
</div>
这个前端代码中activeform的action配置就是后端处理程序的地址,如果使用ajax进行传递参数也是一样的,相当于java前后端分离的后端接口地址,使用activeform更加方便一点(我认为),后期可以专门出一个activeform的使用。
这个提交的地址就是在php的controller文件中进行定义的,是一个单独的function。
2、后端controller文件的设置
public function actionMaterialtransfer()
{
//获取从js中发送来的数据
//$transfer->company = $_POST('company');
//获取移位操作的post请求
$transfer = new CargoTransferForm();
if (Yii::$app->request->isPost){
if($transfer->load(Yii::$app->request->post())){
//对数据的操作写在这里,activeform可以直接用这个接受数据的变量$transfer进行处理
$remark = $transfer->remark
//操作完成以后将transfer变量置空
$transfer = new CargoTransferForm();
}
}
// echo json_encode(array('code' => 'success','obj'=>$addRemark));
return $this->redirect('index21');
Yii::$app->getSession()->setFlash('msg', array('code' => 'success', 'msg' => '货位转移成功'));
}
在这段代码中,首先定义了一个接受表单提交数据的方法,也就是表单提交数据处理程序,用于处理表单提交过来的数据。
$transfer是新定义的一个对象(相当于java对象),这个CargoTransferForm()是在那个model文件夹中定义的一个php类文件,用于存储表单数据的,里边像java类一样,有一些字段和对这些字段的限制。如下图吧(不粘变量了放个图)
像这样,上边是定义的字段名,下边一个规则,最下边是字段对应的标签名,也就是到时候前端让用户填数据的时候,用户看到的那个提示标签的名字。
再回来说这个controller文件,设置一个$transfer是为了存储表单的数据,我这个弹窗的父页面是一个叫index21的页面,我在index21页面的处理程序中也需要定义一个$transfer,也是$transfer = new cargotransferform(),这一个是用来渲染那个页面弹窗的,因为只有表单被提交了程序才能找到这个表单处理程序中的内容,所以弹窗刚刚打开的时候,还不知道有处理程序的存在,也就不知道有当前这个$transfer的存在,所以还需要index21的处理程序中也定义一个(当然,名字随意,我这里重复了反而不好说了,前端页面中使用的那个$transfer是actionIndex21中的)。
再往下是判断程序接收到了从前端传过来的post请求,在下边一行是使用定义的$transfer把表单的数据拿过来了。现在$transfer里边放的就是表单的数据,再对表单的数据进行处理就好了。
最后一定不要忘了,重定向到原来的页面,也就是index21, 就是这句:
return $this->redirect('index21');