扩展 Doctrine2 形式 EntityType

Extend Doctrine2 form EntityType

我正在寻找一种方法来扩展 Symfony 2 EntityType

Symfony\Bridge\Doctrine\Form\Type\EntityType

作为一种新的类型扩展了这个类型,而不是创建一个 FormTypeExtension - 我无法弄清楚。有谁知道这样做的正确方法吗?

我试过以这种方式简单地扩展它:

class NestedEntityType extends EntityType {

    public function getName() {
        return $this->getBlockPrefix();
    }

    public function getBlockPrefix() {
        return 'nested_entity';
    }
}

然后在奏鸣曲管理员 class 我有:

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper->add('types', NestedEntityType::class, [
        'label' => false,
        'multiple' => true,
        'expanded' => true,
        'by_reference' => false
    ]);
}

但不幸的是它会导致致命错误:

Catchable Fatal Error: Argument 1 passed to Symfony\Bridge\Doctrine\Form\Type\DoctrineType::__construct() must implement interface Doctrine\Common\Persistence\ManagerRegistry, none given, called in

我需要保留 EntityType 的全部功能,只有一个例外 - 它的呈现方式。这就是为什么我需要扩展这个类型(我在其他领域使用它,所以我不能只为它修改模板!)。

我正在使用 Symfony 2.8(仅作记录)。

如果您转到 EntityType,您会看到它正在扩展 DoctrineType 并且需要构造函数中的依赖项 -

public function __construct(ManagerRegistry $registry, PropertyAccessorInterface $propertyAccessor = null)
{
    $this->registry = $registry;
    $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
}

因此,您的 class NestedEntityType 使用相同的构造函数并需要相同的依赖项。

其实你需要的是

class NestedEntityType extends AbstractType {

    public function getParent() {
        return EntityType::class;
    } 

    public function getName() {
        return $this->getBlockPrefix();
    } 

    public function getBlockPrefix() {
        return 'nested_entity';
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'class' => YourEntity::class
        ]);
    }
}

UPD:根据EntityType doc,当然需要配置选项。请参阅我添加到代码中的方法。

你不应该直接扩展它,而是使用 parent 选项

/**
 * {@inheritdoc}
 */
public function getParent()
{
    return EntityType::class;
}

所以像

class NestedEntityType extends AbstractType 
{

    public function getName() 
    {
        return $this->getBlockPrefix();
    }

    public function getBlockPrefix() 
    {
        return 'nested_entity';
    }

    /**
     * {@inheritdoc}
     */
    public function getParent()
    {
        return EntityType::class;
    }
}

这样的话,如果您要扩展的 FormType 将某些东西注入(或设置)到构造函数中,您不需要关心,因为 symfony 会为您做这件事。

因此,如果您需要为不同的实体创建可重用的解决方案,在这种情况下您不需要配置选项。

您需要在您的代码中创建一个 elementType,例如

$this->createForm(NestedEntityType::class, null, ['class' => YourEntity::class]);

在这种情况下,您需要将嵌套的 class 实体名称作为选项传递。