Як сконфігурувати порожні дані для класу форми

Дата оновлення перекладу 2023-09-07

Як сконфігурувати порожні дані для класу форми

Опція empty_data дозволяє вам вказати набір порожніх даних для вашого класу форми. Цей набір порожніх даних буде використаний, якщо ви відправите свою форму, але не викличете setData(), або якщо ви передаи дані при створенні вашої форми. Наприклад, у контролері:

1
2
3
4
5
6
7
8
9
10
11
12
public function index()
{
    $blog = ...;

    // $blog передано як дані, так що опція empty_data
    // не потрібна
    $form = $this->createForm(BlogType::class, $blog);

    // не передаються ніякі дані, так що empty_data
    // використовується для отримання "стартових даних"
    $form = $this->createForm(BlogType::class);
}

За замовчуванням, empty_data встановлена у значення null. Або, якщо ви вказали опцію data_class для вашого класу форми, вона буде за замовчуванням приймати новий екземпляр цього класу. Цей екземпляр буде створено шляхом виклику конструктора без аргументів.

Якщо ви хочете перевизначити поведінку за замовчуванням, існує два способи:

Якщо ви не встановили опцію data_class, ви можете передати початкові дані як радом або передати масив рядків (де ключ співпадає з іменем поля), коли тип форми складений.

Спосіб 1: Інстанціювати новий клас

Одна з причин, за яких ви можете захотіти використати цю опцію - це якщо ви хочете використати конструктор, який бере аргументи. Памʼятайте, опція за замовчуванням data_class, викликає конструктор без аргументів:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Form/Type/BlogType.php
namespace App\Form\Type;

// ...
use App\Entity\Blog;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;

class BlogType extends AbstractType
{
    public function __construct(
        private object $someDependency,
    ) {
    }
    // ...

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'empty_data' => new Blog($this->someDependency),
        ]);
    }
}

Ви можете інстанціювати ваш клас так як хочете. У цьому прикладі, ви передаєте деяку залежність у BlogType, а потім використовуєте це для інстанціювання класу Blog. Суть в тому, що ви можете встановити empty_data так, щоб він використовував саме той "новий" обʼєкт, який ви хочете.

Tip

Щоб передати аргументи у конструктор BlogType, вам знадобиться зареєструвати його як сервіс, та тегувати його з form.type. Якщо ви використовуєте конфігурацію services.yaml за замовчуванням , це вже зроблено за вас.

Спосіб 2: Надати замикання

Використання замикання є бажаним методом, так як воно створить обʼєкт лише тоді, коли він потрібен.

Замикання має приймати екземпляр FormInterface в якості першого аргументу:

1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
// ...

public function configureOptions(OptionsResolver $resolver): void
{
    $resolver->setDefaults([
        'empty_data' => function (FormInterface $form): Blog {
            return new Blog($form->get('title')->getData());
        },
    ]);
}