我有一个只有两个列键值的表。我想创建一个允许用户插入3对键值设置的表单。
我需要将3种不同的模型传递给视图吗?或者有可能这样做吗?
答案 0 :(得分:3)
查看此链接: http://www.yiiframework.com/doc/guide/1.1/en/form.table
这被认为是Yii中用于更新创建多个模型的最佳形式。
从本质上讲,对于创建,您可以创建一个for循环,生成您希望可见的多个输入,并在控制器中循环输入以创建新模型。
查看文件:
for ( $settings as $i=>$setting ) //Settings would be an array of Models (new or otherwise)
{
echo CHtml::activeLabelEx($setting, "[$i]key");
echo CHtml::activeLabelEx($setting, "[$i]key");
echo CHtml::error($setting, "[$i]key");
echo CHtml::activeTextField($setting, "[$i]value");
echo CHtml::activeTextField($setting, "[$i]value");
echo CHtml::error($setting, "[$i]value");
}
控制器actionCreate:
$settings = array(new Setting, new Setting, new Setting);
if ( isset( $_POST['Settings'] ) )
foreach ( $settings as $i=>$setting )
if ( isset( $_POST['Setttings'][$i] ) )
{
$setting->attributes = $_POST['Settings'][$i];
$setting->save();
}
//Render View
要更新现有模型,您可以使用相同的方法,但不是创建新模型,而是可以根据$ _POST ['Settings']数组中的键加载模型。
要回答关于将3个模型传递给视图的问题,可以在不传递它们的情况下完成,但是为了验证数据并将正确的错误消息发送到视图,您应该将放置在数组中的三个模型传递给视图在阵列中。
注意:上面的示例应该按原样运行,但不提供模型有效或正确保存的任何验证
答案 1 :(得分:2)
我会给你一个抬头,让你知道你可能会让你的生活变得非常复杂。
我目前正在使用类似于此键值的EAV
图案表格,这里列出了您可能会发现很难或不可能的事情:
CDbCriteria
mergeWith()过滤搜索()(或其他)时“value”的相关元素CGridView
或CListView
如果这只是非常直接的键值而没有相关的实体方面(我猜它是因为它看起来像设置),那么一种方法是:
CActiveRecord
(您将使用此项将条目保存到您的设置表中)CFormModel
创建表单模型,并将其用作表单中的$ model。getAttributes()
以返回数据库数据。我希望这很清楚。 我来给你一些基本的代码设置。请注意我没有测试这个。它应该给你一个粗略的想法。:
设置模型:
class Setting extends CActiveRecord
{
public function tableName()
{
return 'settings';
}
}
SettingsForm模型:
class SettingsForm extends CFormModel
{
/**
* Load attributes from DB
*/
public function loadAttributes()
{
$settings = Setting::model()->findAll();
$this->setAttributes(CHtml::listData($settings,'key','value'));
}
/*
* Save to database
*/
public function save()
{
foreach($this->attributes as $key => $value)
{
$setting = Setting::model()->find(array('condition'=>'key = :key',
'params'=>array(':key'=>$key)));
if($setting==null)
{
$setting = new Setting;
$setting->key = $key;
}
$setting->value = $value;
if(!$setting->save(false))
return false;
}
return true;
}
}
<强>控制器:强>
public function actionSettingsForm()
{
$model = new Setting;
$model->loadAttributes();
if(isset($_POST['SettingsForm']))
{
$model->attributes = $_POST['SettingsForm'];
if($model->validate() && $model->save())
{
//success code here, with redirect etc..
}
}
$this->render('form',array('model'=>$model));
}
表单视图:
$form=$this->beginWidget('CActiveForm', array(
'id'=>'SettingsForm'));
//all your form element here + submit
//(you could loop on model attributes but lets set it up static for now)
//ex:
echo $form->textField($model,'fieldName'); //fieldName = db key
$this->endWidget($form);
如果您想进一步澄清一点(代码等),请告诉我。
PS:对于子孙后代,如果其他人想知道这个和EAV他们可以查看EAV behavior extention或选择更合适的数据库系统,例如MongoDb(那里有一些扩展)或HyperDex