0 follower

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 kontrastu 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 Model, które pozwalają na wczytywanie oraz walidację wielu modeli na raz:

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 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. loadMultiple() uzupełnia modele danymi formularza przesłanymi metodą POST a następnie metoda validateMultiple() waliduje te modele. Po walidacji przekazujemy parametr false do metody 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 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

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

TBD

Found a typo or you think this page needs improvement?
Edit it on github !