Symfony 3:基于特征为实体构建表单

Symfony 3 : Build forms for entities based on Traits

我很难为我的实体构建表单,这些实体本身是用特征构建的。

例如我的 "Article" 实体仅包含类别的 link 和 2 张图片,其余属性在 SeoTrait 中(标题,meta_title,meta_desc、内容等...)、ValidTrait (isValid true/false)...我想将其用于其他实体。

这一切都适用于学说,它生成我的模式,其中包含使用它们的每个实体中的特征的所有字段。问题在于表格:

我已经为 "SEO" 属性创建了 SeoTraitType :

class SeoTraitType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array(
                'label' => 'Nom'
            ))
            ->add('metaTitle', TextType::class, array(
                'label' => 'Meta Title'
            ))
            ->add('metaDescription', TextareaType::class, array(
                'label' => 'Meta Description'
            ))
            ->add('metaKeywords', TextType::class, array(
                'label' => 'Keywords'
            ))
            ->add('content', TextareaType::class, array(
                'label' => 'Content'
            ))
        ;
    }
}

然后我在我的 ArticleType 中使用它:

class ArticleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('seo', SeoTraitType::class, array(
                'label' => 'Seo',
                'mapped' => false
            ))
            ->add('isValid',    ValidTraitType::class,      array(
                'label' => 'Valid',
                'mapped' => false
            ))
            ->add('save',       SubmitType::class,          array(
                'label' => 'form_save',
                'translation_domain' => 'back_default'
            ));
        ;
    }
}

我在这里遇到的两个问题是,当我想将它们嵌入到我的主要实体的表单中时,我必须为 2 个 TraitTypes 设置 mapped => false 然后在我的表单中,我得到了 SeoTrait 字段的 article[seo][name],所以我不能真正使用 $form->handleRequest() 方法和所有...来处理我的表单提交

我想知道在表单组件提供的方法中是否有一种特殊的方法可以做到这一点,或者我是否只需要自己处理请求并自己解析特征数组以在保存之前构建我的实体?我在互联网上真的找不到任何东西:(

解决问题的一种方法是将 class SeoTraitType 转换为 Trait.

喜欢:

trait SeoTraitType
{
    public function buildSEOForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array(
                'label' => 'Nom'
            ))
            ->add('metaTitle', TextType::class, array(
                'label' => 'Meta Title'
            ))
            ->add('metaDescription', TextareaType::class, array(
                'label' => 'Meta Description'
            ))
            ->add('metaKeywords', TextType::class, array(
                'label' => 'Keywords'
            ))
            ->add('content', TextareaType::class, array(
                'label' => 'Content'
            ))
        ;
    }
}

然后:

class ArticleType extends AbstractType
{
    use SeoTraitType;

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->buildSEOForm($builder, $options);

        $builder
            ->add('isValid',    ValidTraitType::class,      array(
                'label' => 'Valid',
                'mapped' => false
            ))
            ->add('save',       SubmitType::class,          array(
                'label' => 'form_save',
                'translation_domain' => 'back_default'
            ));
        ;
    }
}

您也可以使用静态方法执行此操作。不太喜欢 Trait。

好的,Trait 解决方案工作正常,但我选择在此处使用此方法: https://symfony.com/doc/current/form/inherit_data_option.html

非常感谢大家,我很确定解决方案会在文档中的某处,但找不到!