【问题标题】:How to change entity class in form type?如何更改表单类型中的实体类?
【发布时间】:2023-04-04 11:00:01
【问题描述】:

我有树几乎相同的实体类:A、B、C(它们都通过 Doctrine 类表继承扩展了一个超类)。

我有一个表单,允许通过 ChoiceType 选择适当的实体类。事实上,我需要在实体创建时通过表单更改实体类(当它不持久时)

我不知道如何创建将处理的控制器操作:

  • 创建新的 A/B/C 实体
  • 更改实体类(当我更改类字段时 - 表单将提交)
  • 持久化实体

更新 我更新了描述并找到了解决方案(见下方)

【问题讨论】:

  • 有趣的问题。我创建了一个 AbstractController(它扩展了 AController、BController 和 CController)和一个 FormType(它扩展了 AFormType、BFormType 等)。不确定这是最佳做法。
  • 如果没有适当的代码 sn-p,就不能做或告诉你很多事情。
  • 控制器动作是如何被调用的?三种不同的路线?如果是这样,那么只需在路由定义中添加一个内部参数来指示实体。但听起来你应该看看许多现有的 CRUD 库,看看它们是如何做到的。
  • @cerad,我问了这个问题,希望有人能指出实现这种行为的项目或方法。没有时间去挖掘大量的图书馆(
  • 很公平。请注意,您的问题是如此含糊,以至于任何人都可以帮助您是值得怀疑的。希望我错了。

标签: php symfony symfony-forms


【解决方案1】:

我认为您可以轻松地使用 DataTransformer 来做到这一点。

请参阅 http://symfony.com/doc/current/form/data_transformers.html 了解如何记录它。

您可以使用选择内容来选择您需要创建的类。

【讨论】:

  • 谢谢,我忘了 DataTransformers)是的,我认为这比我的方法更容易。将尽快检查)
【解决方案2】:

多种方式。因为我的信息很少,这里有一些选择:

在表单级别:

为您的所有实体添加一个表单类型。添加一个选项来为ChoiceType 配置data_class

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setRequired(['entity_class']);
}

现在在生成表单域时使用它:

$form->add(
    'entity',
    ChoiceType.class,
    ['data_class' => $options['entity_class']]
)

在数据库级别:

查看 Doctrine 如何处理 Single Map Inheritance。它使您能够创建BaseEntity 并从中扩展实体ABC。现在您可以简单地添加ChoiceType(或EntityType)并选择BaseEntity 作为实体。

然后表单将显示一个字段中的所有实体。

【讨论】:

  • 谢谢。是的,我已经使用类表继承。现在尝试使用控制器中的基本实体。在获取子对象实例(A B 或 C)而不是基本扩展对象时遇到一些问题。明天回复结果
  • 我找到了解决方案,请查看:stackoverflow.com/a/39448230/2005817
【解决方案3】:

所以,解决方案看起来像这样。也许有人会觉得它有用

MySuperClassType.php

protected function getAvailableEntityTypes()
{
    $availableTypes = array();

    // here i get all subclasses of MySuperClass to fill em in choice form

    foreach ($this->em->getMetadataFactory()->getAllMetadata() as $classMetadata) {
        if (is_subclass_of($classMetadata->getName(), MySuperClass::class)) {
            $availableTypes[$classMetadata->getName()] = EntityLabelBuilder::getEntityLabelTranslationKey(
                $classMetadata->getName()
            );
        }
    }

    return $availableTypes;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // here i add choice field with all available entity classes

    $builder
        ->add(
            'entityClass',
            ChoiceType::class,
            [
                'mapped' => false,
                'choices' => $this->getAvailableEntityTypes(),
            ]
        );

}

MySuperClassController.php

public function createAction()
{
    // initial entity creation
    $entity = new MySuperClass();

    // here i retrieve form data and recreate entity with class chosen in form
    $request = $this->get('request');
    if (in_array($request->getMethod(), array('POST', 'PUT'))) {
        $form = clone $this->get('my_app.my_super_class.form');
        $form->submit($request);
        $entityClass = $form['entityClass']->getData();

        $entity = new $entityClass();
    }

    // here i call form handler
    return $this->update($spend);
}

【讨论】:

    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 2016-03-20
    • 2012-02-29
    相关资源
    最近更新 更多