Сбор табличных данных
Иногда необходимо обрабатывать несколько моделей одного типа в одной форме. Например, несколько настроек, где каждая настройка хранится как пара «имя-значение» и представлена моделью Setting активной записи. Такой вид формы также часто называют «табличными данными». В отличие от этого, обработка различных моделей разных типов описана в разделе Сложные формы с несколькими моделями.
Ниже показано, как реализовать табличные данные с помощью Yii.
Существует три различных ситуации, которые нужно обработать немного по-разному:
- Обновление фиксированного набора записей из базы данных
- Создание динамического набора новых записей
- Обновление, создание и удаление записей на одной странице
В отличие от форм с одной моделью, описанных ранее, теперь мы работаем с массивом моделей. Этот массив передается в представление для отображения полей ввода для каждой модели в табличном стиле, и мы будем использовать вспомогательные методы yii\base\Model, которые позволяют загружать и проверять сразу несколько моделей:
- Model::loadMultiple() загружает данные из POST в массив моделей.
- Model::validateMultiple() проверяет массив моделей.
Обновление фиксированного набора записей
Начнем с действия контроллера:
<?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]);
}
}
В приведенном коде мы используем indexBy() при извлечении моделей из базы данных для заполнения массива, индексированного первичными ключами моделей. Они позже будут использованы для идентификации полей формы. Model::loadMultiple() заполняет несколько моделей данными из формы POST, а Model::validateMultiple() проверяет все модели сразу. Поскольку мы уже проверили наши модели ранее, используя validateMultiple(), мы теперь передаем false в качестве параметра в save(), чтобы не выполнять проверку дважды.
Теперь форма, которая находится в 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();
Здесь для каждой настройки мы отображаем имя и поле ввода со значением. Важно добавить правильный индекс к имени поля ввода, поскольку именно так Model::loadMultiple() определяет, какую модель заполнить какими значениями.
Создание динамического набора новых записей
Создание новых записей аналогично обновлению, за исключением части, где мы инициализируем модели:
public function actionCreate()
{
$count = count(Yii::$app->request->post('Setting', []));
$settings = [new Setting()];
for($i = 1; $i < $count; $i++) {
$settings[] = new Setting();
}
// ...
}
Здесь мы создаем начальный $settings массив, содержащий по умолчанию одну модель, чтобы всегда хотя бы одно текстовое поле было видно в представлении. Кроме того, мы добавляем больше моделей для каждой строки ввода, которую мы могли получить.
В представлении вы можете использовать JavaScript для динамического добавления новых строк ввода.
Комбинирование обновлений, создания и удаления на одной странице
Примечание: Этот раздел находится в разработке.
В нём пока нет содержимого.
TBD
© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc-2.0/guide-input-tabular-input.html