Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

4.0 KiB

Odczytywanie tablicowych danych wejściowych

Czasami zachodzi potrzeba obsłużenia wielu modeli tego samego rodzaju w jednym formularzu. Dla przykładu: ustawienia, gdzie każde z nich jest przechowywane jako para klucz-wartość, i każde z nich jest reprezentowane przez model Setting active record. Dla kontrastru, obsługa wielu modeli różnych rodzajów pokazana jest w sekcji Pobieranie danych dla wielu modeli.

Poniższe przykłady pokazują jak zaimplementować tablicowe dane wejściowe w Yii.

Występują trzy różne sytuacje, które należy obsłużyć inaczej:

  • Aktualizacja określonej liczby rekordów z bazy danych
  • Dynamiczne tworzenie nowych rekordów
  • Aktualizacja, tworzenie oraz usuwanie rekordów na jednej stronie

W porównaniu do formularza z pojedyńczym modelem, wytłumaczonym poprzednio, pracujemy teraz na tablicy modeli. Tablica przekazywana jest do widoku, aby wyświetlić pola wejściowe dla każdego modelu w stylu tabeli, użyjemy do tego metod pomocniczych z yii\base\Model, które pozwalają na wczytywanie oraz walidację wielu modeli na raz:

  • yii\base\Model::loadMultiple() wczytuje dane z tablicy POST do tablicy modeli.
  • yii\base\Model::validateMultiple() waliduje tablicę modeli.

Aktualizacja określonej liczby rekordów

Zacznijmy od akcji kontrolera:

<?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]);
    }
}

W powyższym kodzie używamy yii\db\ActiveQuery::indexBy() podczas pobierania danych z bazy danych aby zasilić tablicę modelami zaindeksowanymi przez główny klucz. Będzie to później użyte do zidentyfikowania pól formularza. yii\base\Model::loadMultiple() uzupełnia modele danymi formularza przesłanymi metodą POST a następnie metoda yii\base\Model::validateMultiple() waliduje te modele. Po walidacji przekazujemy parametr false do metody yii\db\ActiveRecord::save() aby nie uruchamiać walidacji ponownie.

Przejdziemy teraz do formularza w widoku 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();

Dla każdego z ustawień renderujemy nazwę oraz pole wejściowe z wartością. Bardzo ważne jest dodanie odpowiedniego indeksu do nazwy pola, ponieważ dzięki temu metoda yii\base\Model::loadMultiple() określa który model powinna uzupełnić przekazanymi wartościami.

Dynamiczne tworzenie nowych rekordów

Tworzenie nowych rekordów jest podobne do ich aktualizacji, poza częścią, w której instancjujemy modele:

public function actionCreate()
{
    $count = count(Yii::$app->request->post('Setting', []));
    $settings = [new Setting()];
    for($i = 1; $i < $count; $i++) {
        $settings[] = new Setting();
    }

    // ...
}

Tworzymy tutaj początkową tablicę $settings zawierającą domyślnie jeden model, dlatego zawsze co najmniej jedno pole będzie widoczne w widoku. Dodatkowo dodajemy więcej modeli dla każdej linii pól wejściowych jakie otrzymaliśmy.

W widoku możemy użyć kodu javascript do dynamicznego dodawania nowych linii pól wejściowych.

Aktualizacja, tworzenie oraz usuwanie rekordów na jednej stronie

Note: Ta sekcja nie została jeszcze skończona.

TBD