Как сконфигурировать пустые данные для класса формы

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

Как сконфигурировать пустые данные для класса формы

Опция empty_data позволяет вам указать набор пустых данных для вашего классаформы. Этот набор пустых данных будет использован, если вы отправите свою форму, но не вызовете setData(), или если вы передали данные при создании вашей формы. Например, в контроллере:

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

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

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

По умолчанию, empty_data установлена в значение null. Или, если вы указали опцию data_class для вашего класса формы, она будет по умолчанию принимать новый экземпляр этого класса. Этот экземпляр будет создан путём вызова конструктора без аргументов.

Если вы хотите переопределить поведение по умолчанию, существует два способа:

If you didn't set the data_class option, you can pass the initial data as string or pass an array of strings (where the key matches the field name) when the form type is compound.

Способ 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());
        },
    ]);
}