如何嵌入表单
通常,您会希望构建一个表单,其中包含来自许多不同对象的字段。例如,注册表单可能包含属于 User
对象以及许多 Address
对象的数据。幸运的是,这可以通过 Form 组件来实现。
嵌入单个对象
假设每个 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;
}
接下来,向 Task
类添加一个新的 category
属性
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;
}
}
提示
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,
]);
}
}
最终目标是允许在任务表单本身中修改 Task
的 Category
。为了实现这一点,向 TaskType
对象添加一个 category
字段,其类型是新 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);
}
现在可以与 TaskType
类中的字段一起呈现来自 CategoryType
的字段。
以与原始 Task
字段相同的方式呈现 Category
字段
1 2 3 4 5 6 7 8
{# ... #}
<h3>Category</h3>
<div class="category">
{{ form_row(form.category.name) }}
</div>
{# ... #}
当用户提交表单时,Category
字段的提交数据用于构造 Category
的实例,然后将其设置在 Task
实例的 category
字段上。
Category
实例可以通过 $task->getCategory()
自然地访问,并且可以持久化到数据库或以您需要的任何方式使用。
嵌入表单集合
您还可以将表单集合嵌入到一个表单中(想象一下一个包含许多 Product
子表单的 Category
表单)。这可以通过使用 collection
字段类型来完成。
有关更多信息,请参阅如何嵌入表单集合文章和CollectionType参考。
本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。