Symfony 3:基于Traits构建实体表单

时间:2017-08-25 15:32:12

标签: forms symfony embed traits

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

例如,我的“文章”实体仅包含指向该类别的链接和2个图片,其余属性位于SeoTrait(标题,元标题,元数据,内容等等),ValidTrait(isValid true / false)...我想用于其他实体。

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

我为“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'
            ));
        ;
    }
}

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

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

2 个答案:

答案 0 :(得分:2)

解决问题的一种方法是将您的班级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的忠实粉丝。

答案 1 :(得分:1)

好的,所以Trait解决方案运行正常,但我选择在这里使用此方法: https://symfony.com/doc/current/form/inherit_data_option.html

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