gpt4 book ai didi

forms - Symfony 2.8+, Doctrine 继承和形式

转载 作者:行者123 更新时间:2023-12-02 03:14:44 26 4
gpt4 key购买 nike

在我开始之前,请注意我正在学习 symfony 所以请记住这一点!我只是想了解它是如何工作的。
这是我想要实现的目标:

我想使用 Doctrine 制作一个实体继承的工作示例。所以这就是我的例子的样子:

  • 抽象父类:字符
  • child 类 1 : 魔术师
  • child 类 2 : 战士
  • child 类3:弓箭手

  • 因此,在阅读了一些文档后,我决定使用 Doctrine 的 STI(单表继承)。

    父类:
    /**
    * Character
    *
    * @ORM\Table(name="character")
    * @ORM\Entity(repositoryClass="AppBundle\Repository\CharacterRepository")
    * @ORM\InheritanceType("SINGLE_TABLE")
    * @ORM\DiscriminatorColumn(name="discr", type="string")
    * @ORM\DiscriminatorMap({"magician_db" = "Magician", "warrior_db" = "Warrior", "archer_db" = "Archer"})
    */

    abstract class Character{
    protected id;
    protected name;
    public function getId();
    public function getName();
    public function setName();
    }

    child 类 1 :
    class Warrior extends Character{
    protected armor;
    public function battleShout();
    }

    child 类2:
    class Magician extends Character{
    protected silk;
    public function spellAnnounce();
    }

    child 类3:
    class Archer extends Character{
    protected leather;
    public function arrows();
    }

    我设法在我的数据库中创建了表,并且我成功地加载了我的装置以进行测试。我还制作了我的主要 View (列出所有字符)。

    我的问题:
    现在我希望能够使用单个表单创建、编辑和删除列表中的特定字符。所以例如我会有一个 'type' 选择字段,我可以在其中选择 'warrior'、'magician' 或 'archer' 然后我就可以填写所选实体的特定字段。所以假设我在表格中选择了“战士”,然后我希望能够设置 盔甲属性 (当然还有 parent 之一)并将其保存在数据库中。

    我不知道该怎么做,因为我的父类是抽象的,所以我无法基于该对象创建表单。

    提前感谢您的帮助,我真的需要它!

    PS:如果有更好的解决方案/实现,请不要犹豫!

    最佳答案

    最简单的方法是提供所有字段并根据“类型”值删除它们。

    为此,您必须在客户端(用于显示目的)和服务器端(以便无法在您的实体中更改已删除的字段)上实现逻辑。

    在客户端:

  • 使用 javascript 隐藏无法为每个“类型”更改设置的类型(您可以使用 JQuery 和 .hide() 函数)。

  • 服务器端:
  • 将 PRE_BIND 事件添加到您的表单类型,以从表单中删除字段:

  • http://symfony.com/doc/current/components/form/form_events.html#a-the-formevents-pre-submit-event

    您的表单应如下所示:
    // ...

    use Symfony\Component\Form\FormEvent;
    use Symfony\Component\Form\FormEvents;
    use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

    $form = $formFactory->createBuilder()
    ->add('type', ChoiceType::class)
    ->add('armor')
    ->add('silk')
    ->add('leather')
    ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
    $submittedData = $event->getData();
    $form = $event->getForm();

    switch($submittedData['type'])
    {
    case 'warrior':
    $form->remove('silk');
    $form->remove('leather');
    break;
    case 'magician':
    $form->remove('armor');
    $form->remove('leather');
    break;
    case 'archer':
    $form->remove('armor');
    $form->remove('silk');
    break;
    default:
    throw new ...;
    }
    })
    ->getForm();

    // ...

    编辑

    处理单表继承,不能使用抽象类,基类必须是普通实体。

    在您的表单中,只需将类设置为 AppBundle\角色 .

    在创建角色的 Controller 操作中,您必须使用以下内容启动您的实体:
    if($request->isMethod('POST')){
    // form has been submitted
    switch($request->get('type'))
    {
    case 'warrior':
    $entity = new Warrior();
    ...
    }
    }
    else{
    // form has not been submitted, default : Warrior
    $entity = new Warrior();
    }

    通过编辑和删除字符,您可以直接处理字符实体。

    我建议不要让用户通过编辑改变类型,见 Doctrine: Update discriminator for SINGLE_TABLE Inheritance

    关于forms - Symfony 2.8+, Doctrine 继承和形式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37697331/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com