Symfony2表单-如何使用附加字段呈现可链接到当前实体的所有实体

Symfony2表单-如何使用附加字段呈现可链接到当前实体的所有实体,symfony,symfony-forms,Symfony,Symfony Forms,我需要实现有趣的功能,但我不知道正确的解决方案。看看下面的例子 我有两个实体: 车辆(可以是汽车、火车、自行车、双腿或其他) 零件(可以是线圈、车轮、座椅、车窗、手制动器等) 当我创建或编辑车辆时,我应该有可能为该车辆选择任何零件的数量。所以,车辆表单应该包含所有零件,每个零件都应该有额外的字段“金额”。 所以,若金额大于0,则应创建关系。如果零件数量等于零,则此零件与车辆之间没有关系 公平地说,我创建了其他实体来存储与其他字段的关系: VehiclePart(存储车辆id、零件id和该零

我需要实现有趣的功能,但我不知道正确的解决方案。看看下面的例子

我有两个实体:

  • 车辆(可以是汽车、火车、自行车、双腿或其他)
  • 零件(可以是线圈、车轮、座椅、车窗、手制动器等)
当我创建或编辑车辆时,我应该有可能为该车辆选择任何零件的数量。所以,车辆表单应该包含所有零件,每个零件都应该有额外的字段“金额”。 所以,若金额大于0,则应创建关系。如果零件数量等于零,则此零件与车辆之间没有关系

公平地说,我创建了其他实体来存储与其他字段的关系:

  • VehiclePart(存储车辆id、零件id和该零件的数量)
该实体通过与车辆和零件实体的多个关系进行链接

有一个问题:如何以车辆形式呈现所有可用零件,以及如何在零件数量大于0时执行检查以保持关系


我需要一个建议-什么是适合我需求的适当方法?真的很抱歉我的英语

这里有一个方法供你尝试

你可以用它来制作你的表格。这将很好地工作,因为它允许您从所有可用零件的选择列表中动态地向车辆添加零件

这样,您就不必担心数量>0时的持久性问题,如果您添加了一个零件和一个数量,它就被添加了。要将数量归零,只需完全移除零件

你最初的想法并不那么容易。您必须使用动态方式添加表单字段。保存表单时,您可以使用表单事件侦听器访问基础车辆实体,然后在保留数据之前删除任何数量为0的车辆部件实体

这是可以做到的,但我会推荐第一个选项,因为它简单得多

编辑:添加了基本概述。虽然我时间不够,但很粗糙对不起

侦听器添加一个字段

<?php

namespace Your\NameSpace\Form\EventListener;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class AddYourTypeSubscriber implements EventSubscriberInterface
{
    private $factory;

    public function __construct(FormFactoryInterface $factory) {

        $this->factory = $factory;
    }

    public static function getSubscribedEvents() {

        return array(FormEvents::PRE_SET_DATA => 'addYourItem');
    }

    public function addYourItem(FormEvent $event) {

        $data = $event->getData();
        $form = $event->getForm();

        if (!$data instanceof YourClass) {
            return;
        }

        /** @var YourClass $yourClassItem */
        $yourClassItem = $data;

        // You might have some criteria around what you would or would not add
        $form->add(
            $this->factory->createNamed('yourChildPropertyOrCollectionField', new YourChildPropertyOrCollectionFieldFormType() /** also could be a form type service */, null, array('auto_initialize' => false))
        );
    }
}

是的,昨天我已经用了你刚才描述的方法)所以,我创建了PRE_SET_DATA listener将每个零件添加到车辆表单中,POST_SUBMIT listener从集合中删除所有零价格零件。是的,第一个实现非常简单,但是第二个更正确。谢谢你,理查德!明天,我将添加一个代码列表,以帮助其他人使用它solution@StepanYudin我在找你刚才描述的东西。你仍然愿意分享你的解决方案吗?它可以帮助其他人…@wimvds我添加了一个基本概述-是symfony 2.3,因此对于2.7+@wimvds可能不是100%准确。您是否有一个工作示例,在Richard提供的代码中,我错过了添加可链接到的数据的位置。
<?php

namespace Your\NameSpace\Form\EventListener;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RemoveTypeBasedOnSomeCriteriaSubscriber implements EventSubscriberInterface
{
    private $factory;

    public function __construct(FormFactoryInterface $factory) {

        $this->factory = $factory;
    }

    public static function getSubscribedEvents() {

        return array(FormEvents::POST_SUBMIT => 'removeItemsBasedOnSomeCriteria');
    }

    /**
     * Remove items we do not want
     *
     * @param FormEvent $event
     */
    public function removeItemsBasedOnSomeCriteria(FormEvent $event) {

        $data = $event->getData();
        $form = $event->getForm();

        if (!$data instanceof YourClass) {
            return;
        }

        // If the form isn't valid we don't need to action this as we have
        // yet to persist.

        if (!$form->isValid()) {
            return;
        }

        // From here you can do anything with YourClass

        if ($yourClass->failsSomeCriteria()) {

            $yourClass->setSomeChildProperty(null); // etc
        }
    }
}
    // add item subscriber in buildform method of your form type
    $addYourSubscriberSubscriber = new AddYourTypeSubscriber($builder->getFormFactory());
    $builder->addEventSubscriber($addYourSubscriberSubscriber);

    // remove item subscriber in buildform method of your form type
    $removeTypeBasedOnSomeCriteriaSubscriber = new RemoveTypeBasedOnSomeCriteriaSubscriber($builder->getFormFactory());
    $builder->addEventSubscriber($removeTypeBasedOnSomeCriteriaSubscriber);