假设这么一个场景: 有一个通过 Yii ActiveForm 构建的表单,里面所有的字段都是虚拟的,比如说 这个表单的字段来自于一个 JSON 或者说数据库的结果集,需要实现同一个模型,根据不同的传参,构建不同的表单项。
问题: Yii 的表单是通过模型来创建的,也就是说我有这个表单项,模型中必须有对应的字段(成员属性),否则就会报错。且这个成员属性在模型实例化之后是不允许添加的,那么我们如何去动态的添加这些表单项的字段?
解决思路: 既然模型字段都是不存在的,我们干脆用一个虚拟的模型,不是说这个模型文件不存在,而是指模型文件不对应任何实际的数据表。
那么我们只需要在实例化模型的时候,传入动态的字段,然后在对应的 rules()
、attributes()
、attributeLabels()
方法里面返回我们的动态字段,就可以实现需要的效果。
模型部分
创建一个虚拟的模型,重写构造方法,传入字段,赋值给成员属性 $field
<?php
namespace app\models;
use Attribute;
use yii\db\ActiveRecord;
class Actor extends ActiveRecord
{
public $field;
public function __construct($field)
{
$this->field = $field;
parent::__construct([]);
}
public function rules()
{
return [
[$this->field, 'required']
];
}
public function attributes()
{
return $this->field;
}
}
控制器部分
<?php
namespace app\controllers;
use Yii;
use Yii\base\Controller;
use app\models\Actor;
class TestController extends Controller
{
public function actionIndex()
{
/**
* 动态创建的字段,在实例化模型的时候传递进去
* 这里只是为了测试,实际应用的时候可以是从其他途径来的数组:
* 比如 JSON 动态转换、数据库查询出的结果集等等
*/
$field = ['username','json','token'];
$model = new Actor($field);
if (Yii::$app->request->getIsGet()) {
return $this->render('index',['model' => $model]);
}
// 装载数据
$model->load(Yii::$app->request->post());
// 获取模型提交的数据
var_dump($model->getDirtyAttributes());
}
}
视图部分
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$form = ActiveForm::begin([
'id' => 'login-form',
'options' => ['class' => 'form-horizontal'],
]) ?>
<!-- 遍历模型中的字段 在页面上构建输入框 -->
<? foreach($model->field as $field) { ?>
<?= $form->field($model, $field) ?>
<? }?>
<div class="form-group">
<div class="col-lg-offset-1 col-lg-11">
<?= Html::submitButton('submit', ['class' => 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end() ?>
标签:return,模型,Yii,表单,field,思路,model
From: https://www.cnblogs.com/dbkuaizi/p/17806535.html