有時你需要在一個表單中以單一的形式處理多個模型。例如,有多個設(shè)置,每個設(shè)置存儲為一個 name-value,并通過 Setting
活動記錄模型來表示。這種形式也常被稱為“列表輸入”。與此相反,處理不同模型的不同類型,在多模型同時輸入章節(jié)中介紹。
下面展示了如何在 Yii 中收集列表輸入。
在三種不同的情況下,所需處理的略有不同:
與之前介紹的單一模型表單相反,我們現(xiàn)在用的是一個數(shù)組類的模型。這個數(shù)組將每個模型傳遞到視圖并以一種類似于表格的方式來顯示表單字段。我們使用 [[yii\base\Model]] 助手類方法來一次性地加載和驗證多模型數(shù)據(jù):
讓我們從控制器的動作開始:
<?php
namespace app\controllers;
use Yii;
use yii\base\Model;
use yii\web\Controller;
use app\models\Setting;
class SettingsController extends Controller
{
// ...
public function actionUpdate()
{
$settings = Setting::find()->indexBy('id')->all();
if (Model::loadMultiple($settings, Yii::$app->request->post()) && Model::validateMultiple($settings)) {
foreach ($settings as $setting) {
$setting->save(false);
}
return $this->redirect('index');
}
return $this->render('update', ['settings' => $settings]);
}
}
在上面的代碼中,當用模型來從數(shù)據(jù)庫獲取數(shù)據(jù)時,我們使用 [[yii\db\ActiveQuery::indexBy()|indexBy()]] 來讓模型的主鍵成為一個數(shù)組的索引。其中 [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] 用于接收以 POST 方式提交的表單數(shù)據(jù)并填充多個模型,[[yii\base\Model::validateMultiple()|Model::validateMultiple()]] 一次驗證多個模型。正如我們之前驗證的模型,使用了 validateMultiple()
,現(xiàn)在通過傳遞 false
作為 [[yii\db\ActiveRecord::save()|save()]]的一個參數(shù)使其不會重復(fù)驗證兩次。
現(xiàn)在在 update
視圖的表單:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$form = ActiveForm::begin();
foreach ($settings as $index => $setting) {
echo $form->field($setting, "[$index]value")->label($setting->name);
}
ActiveForm::end();
在這里,我們?yōu)槊總€設(shè)置渲染了名字和一個帶值的輸入。重要的是給 input name 增加添加適當?shù)乃饕?,因為這是由 [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] 來決定以哪些值來填補哪個模型。
創(chuàng)造新的記錄與修改記錄很相似,除部分實例化模型不同之外:
public function actionCreate()
{
$count = count(Yii::$app->request->post('Setting', []));
$settings = [new Setting()];
for($i = 1; $i < $count; $i++) {
$settings[] = new Setting();
}
// ...
}
在這里,我們創(chuàng)建了一個初始的 $settings
數(shù)組包含一個默認的模型,所以始終至少有一個文本字段是可見的。此外,我們?yōu)槊總€可能會收到的輸入行添加更多的模型。
在視圖中,可以使用 JavaScript 來動態(tài)地添加新的輸入行。
注意:此章節(jié)正在開發(fā)中。
還沒有內(nèi)容。
TBD