Як вбудовувати форми
Дата оновлення перекладу 2023-09-07
Як вбудовувати форми
Часто вам може захотітися побудувати форму, яка міститиме поля з багатьох різних
обʼєктів. Наприклад, форма реєстрації може містити дані, що належать обʼєкту User
,
а також багато обʼєктів Address
. На щастя, це просто та природньо за допомогою
компонента Форма.
Вбудовування одного обʼєкта
Уявіть, що кожний Task
належить простому обʼєкту Category
. Почніть,
авжеж, зі створення обʼєкта Category
:
1 2 3 4 5 6 7 8 9 10
// src/Entity/Category.php
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Category
{
#[Assert\NotBlank]
public string $name;
}
Далі, додайте нову властивість category
до класу Task
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// ...
class Task
{
// ...
#[Assert\Type(type: Category::class)]
#[Assert\Valid]
protected ?Category $category = null;
// ...
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): void
{
$this->category = $category;
}
}
Tip
Обмеження Valid
було додано до властивості category
. Це створює каскадне
включення валідації у відповідну сутність. Якщо ви пропустите це обмеження, то
дочірня сутність не буде валідована.
Тепер, коли ваш додаток був оновлений так, щоб відображати нові вимоги,
створіть клас форми так, щоб обʼєкт Category
можна було змінювати
користувачу:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// src/Form/CategoryType.php
namespace App\Form;
use App\Entity\Category;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CategoryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('name');
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Category::class,
]);
}
}
Кінцева ціль - дозволити Category
класу Task
підлягати змінам прямо
всередині форми задачі. Щоб досягти цього, додайте поле category
до
обʼєкта TaskType
, тип якого - екземпляр нового класу CategoryType
:
1 2 3 4 5 6 7 8 9
use App\Form\CategoryType;
use Symfony\Component\Form\FormBuilderInterface;
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// ...
$builder->add('category', CategoryType::class);
}
Поля з CategoryType
тепер можуть бути відоражені на ряду з полями з
TaskType
.
Відобразіть поля Category
таким же чином, як оригінальні поля Task
:
1 2 3 4 5 6 7 8
{# ... #}
<h3>Category</h3>
<div class="category">
{{ form_row(form.category.name) }}
</div>
{# ... #}
Коли користувач відправляє форму, відправлені дані для полів Category
використовуються для створення сутності Category
, яка потім встановлюється
у поле category
екземпляру Task
.
До екземпляру Category
можна отримати доступ через $task->getCategory()
і
його можна зберегти у базі даних або використовувати так, як вам це потрібно.
Вбудовування колекції форм
Ви також можете вбудувати колекцію форм в одну форму (уявіть форму Category
з багатьма підформами Product
). Це робитьсся шляхом використання типу поля
collection
.
Щоб дізнатися більше, дивіться статтю Как вбудувати колекцію форм та довідник CollectionType.