首页 > 解决方案 > Symfony 4:在 Sonata 的 configureFormFields 方法中使用现有的表单类型类

问题描述

我知道我可以将类型构建器中的单个表单元素拉到表单映射器中,如文档中所述

您可以将 SymfonyFormBuilderInterface实例添加到 FormMapper. 这允许您重新使用模型表单类型。使用 a 添加字段时FormBuilderInterface,会猜测类型。

鉴于你有PostType这样的:

use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\AbstractType;

class PostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('author', EntityType::class, [
                'class' => User::class
            ])
            ->add('title', TextType::class)
            ->add('body', TextareaType::class)
        ;
    }
}

你可以像这样重用它:

use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use App\Form\PostType;

class Post extend AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $builder = $formMapper->getFormBuilder()->getFormFactory()->createBuilder(PostType::class);

        $formMapper
            ->with('Post')
                ->add($builder->get('title'))
                ->add($builder->get('body'))
            ->end()
            ->with('Author')
                ->add($builder->get('author'))
            ->end()
        ;
    }
}

但是,如果您只想让 Sonata 按原样使用该确切类型,这会让人感觉很笨拙。

因此,我想知道是否有一种速记可以告诉奏鸣曲简单地按原样使用整个表单类型。

就像是:

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper->mapForm((new PostType()));
}

标签: phpsymfonysymfony4sonata-adminsonata

解决方案


也许使用的较短版本inherit_data可能是您正在寻找的。

https://symfony.com/doc/current/form/inherit_data_option.html

来自:如何在 Sonata Admin 中继承 FormType?

Post例子

use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use App\Form\PostType;

class PostAdmin extend AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add(
                'post',  // name does not seem to matter
                PostType::class, 
                [
                    'inherit_data' => true,
                ]
            );
    }
}

使用PostAdmin(and PostType) 在 1:m 关系中映射子记录也可以,但是inline选项存在问题,并且表格视图似乎没有按预期将其呈现在单独的列中。

// Thread 1:m Post

/**
 * @ORM\Entity
    ...
 */
class Thread
{
    protected $title = '';

    /**
     * @var Post[]|ArrayCollection
     *
     * @ORM\OneToMany(...)
     */
    protected posts;
}
class Post extend AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper->
            ->with('Thread')
            ->add('title')
            ->add(
                'posts',
                'sonata_type_collection',
                [
                    'label'        => 'Posts',
                    'required'     => false,
                    'by_reference' => false,
                ],
                [
                    'edit'     => 'inline', // does not seem to work
                    'inline'   => 'table',  // takes up one column in table
                    'multiple' => true,     // one row per entry
                ]
            );
    }
}


推荐阅读