Symfony 2.8+,教义继承和形式

2024-03-23

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

我想使用学说制作一个实体继承的简单示例。这就是我的示例的样子:

  • 摘要父类:特点
  • 儿童1班:Magician
  • 儿童2班:Warrior
  • 儿童3班:Archer

因此,在阅读了一些文档后,我决定使用 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();
}

儿童1级:

class Warrior extends Character{
       protected armor;
       public function battleShout();
}

儿童2班:

class Magician extends Character{
       protected silk;
       public function spellAnnounce();
}

儿童3级:

class Archer extends Character{
       protected leather;
       public function arrows();
}

我设法在数据库中创建表,并成功加载用于测试目的的装置。我还使我的主视图起作用(列出所有角色)。


我的问题 :现在我希望能够使用单个表单创建、编辑和删除列表中的特定字符。例如我会有一个“类型”选择字段,我可以在其中选择“战士”、“魔术师”或“弓箭手”然后我就可以填写所选实体的特定字段。假设我在表单中选择“战士”,那么我希望能够设置护甲属性(当然还有父母之一)并将其保存在数据库中。

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

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

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


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

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

在客户端:

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

在服务器端:

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

http://symfony.com/doc/current/components/form/form_events.html#a-the-formevents-pre-submit-event 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();

// ...

EDIT

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

在您的表单中,只需将班级设置为应用程序包\角色.

在创建角色的控制器操作中,您必须使用如下内容启动实体:

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();
}

通过编辑和删除角色,可以直接处理角色实体。

我建议不要让用户通过编辑更改类型,请参阅原则:更新 SINGLE_TABLE 继承的鉴别器 https://stackoverflow.com/questions/12610421/doctrine-update-discriminator-for-single-table-inheritance

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Symfony 2.8+,教义继承和形式 的相关文章

随机推荐