扩展Doctrine2形式的EntityType

时间:2016-09-15 13:32:32

标签: php symfony doctrine-orm sonata-admin symfony2-forms

我正在寻找扩展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';
    }
}

然后在奏鸣曲管理班我有:

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

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

  

捕获致命错误:参数1传递给   Symfony \ Bridge \ Doctrine \ Form \ Type \ DoctrineType :: __ construct()必须   实现接口Doctrine \ Common \ Persistence \ ManagerRegistry,none   给出,在

中调用

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

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

3 个答案:

答案 0 :(得分:6)

您不应该直接扩展它,而是使用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会为你做。

答案 1 :(得分:1)

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

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

因此,您的类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,您当然需要配置选项。请参阅方法I已添加到代码中。

答案 2 :(得分:1)

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

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

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

在这种情况下,您需要传递一个嵌套类Entity的名称作为选项。