mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 18:47:33 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			102 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| Табличный ввод
 | ||
| ========================
 | ||
| 
 | ||
| Иногда возникает необходимость обработки нескольких моделей одного вида в одной форме. Например, несколько параметров, каждый из которых сохраняется как пара имя-значение и представляется моделью [Active Record](db-active-record.md) `Setting`.
 | ||
| Такой тип форм часто называют "табличным вводом".
 | ||
| Обработка данных нескольких моделей разных видов в одной форме описана в разделе [Работа с несколькими моделями](input-multiple-models.md).
 | ||
| 
 | ||
| Дальше будет рассмотрен вариант реализации табличного ввода при помощи Yii.
 | ||
| 
 | ||
| Выделим три сценария, которые потребуют немного разных подходов:
 | ||
| - Изменение фиксированного набора записей из базы данных;
 | ||
| - Создание произвольного набора записей;
 | ||
| - Изменение, создание и удаление записей на одной странице.
 | ||
| 
 | ||
| В отличие от форм с одной моделью, рассмотренных ранее, теперь будем иметь дело с массивом моделей. Этот массив передается в представление и для каждой модели отображаются поля ввода в табличном виде. Для загрузки и валидации нескольких моделей сразу будем использовать вспомогательные методы класса [[yii\base\Model]]:
 | ||
| 
 | ||
| - [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] загружает POST-данные в массив моделей;
 | ||
| - [[yii\base\Model::validateMultiple()|Model::validateMultiple()]] валидирует массив моделей.
 | ||
| 
 | ||
| ### Изменение фиксированного набора записей
 | ||
| 
 | ||
| Начнем с действия контроллера:
 | ||
| 
 | ||
| ```php
 | ||
| <?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]);
 | ||
|     }
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| В коде выше, для получения из базы данных массива моделей, индексированного по главному ключу, использован метод [[yii\db\ActiveQuery::indexBy()|indexBy()]]. В дальнейшем будем использовать это для идентификации полей формы. Метод [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] загружает данные запроса POST в массив моделей, а метод [[yii\base\Model::validateMultiple()|Model::validateMultiple()]] проводит валидацию всех моделей. Так как модели уже прошли валидацию, мы передаем методу [[yii\db\ActiveRecord::save()|save()]] параметр `false` для отключения повторной валидации.
 | ||
| 
 | ||
| Теперь займемся формой в представлении `update`:
 | ||
| 
 | ||
| ```php
 | ||
| <?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();
 | ||
| ```
 | ||
| 
 | ||
| Для каждого элемента массива `$settings` генерируется имя и поле ввода значения. Важно указать правильный индекс в имени поля ввода значения, так как [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] определяет модель по этому индексу.
 | ||
| 
 | ||
| 
 | ||
| ### Создание произвольного набора записей
 | ||
| 
 | ||
| Процесс создания новых записей похож на их изменение, за исключением части, где создаются новые модели:
 | ||
| 
 | ||
| ```php
 | ||
| public function actionCreate()
 | ||
| {
 | ||
|     $count = count(Yii::$app->request->post('Setting', []));
 | ||
|     $settings = [new Setting()];
 | ||
|     for($i = 1; $i < $count; $i++) {
 | ||
|         $settings[] = new Setting();
 | ||
|     }
 | ||
| 
 | ||
|     // ...
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Сначала создается массив `$settings`, содержащий один экземпляр модели, так что по умолчанию в представлении всегда будет отображено хотя бы одно поле. Дополнительно, добавляются модели для каждой полученной строки ввода.
 | ||
| 
 | ||
| В представлении возможно использовать JavaScript для добавления новых полей динамически.
 | ||
| 
 | ||
| 
 | ||
| ### Изменение, создание и удаление записей на одной странице
 | ||
| 
 | ||
| > Note: Раздел находится в разработке
 | ||
| 
 | ||
| TBD
 | 
