Php Symfony:具有继承类的窗体

Php Symfony:具有继承类的窗体,php,symfony,discriminator,Php,Symfony,Discriminator,我试图弄清楚在使用Symfony(2.8.6)继承的类类型时如何处理表单 我在下面创建了一个[非常]简单的例子来说明我要做的事情。这是有问题的,但这只是为了说明我的问题 如何只提供从控制器到细枝模板的一个表单,以便有一个字段来选择应该使用的“类型”(鉴别器)?我是否应该简单地创建另一个变量,例如在每个类中硬编码的“type” 提交表单后,我如何确定控制器中应该使用哪个类,在“新建”或“编辑”操作中?我试着从参数包中提取它,创建一个合适的实体和表单,然后使用$form->handleRequest

我试图弄清楚在使用Symfony(2.8.6)继承的类类型时如何处理表单

我在下面创建了一个[非常]简单的例子来说明我要做的事情。这是有问题的,但这只是为了说明我的问题

  • 如何只提供从控制器到细枝模板的一个表单,以便有一个字段来选择应该使用的“类型”(鉴别器)?我是否应该简单地创建另一个变量,例如在每个类中硬编码的“type”
  • 提交表单后,我如何确定控制器中应该使用哪个类,在“新建”或“编辑”操作中?我试着从参数包中提取它,创建一个合适的实体和表单,然后使用$form->handleRequest($request)。。。但当有可能属于另一种类型的额外字段时,它似乎不起作用
  • 如果有人能给我指出Github回购协议或类似的事情,我会非常感激。谢谢你抽出时间

    如果这些是我的课程:

     /**
     * @ORM\Entity
     * @ORM\InheritanceType("SINGLE_TABLE")
     * @ORM\DiscriminatorColumn(name="discr", type="string")
     * @ORM\DiscriminatorMap("truck" = "Truck", "Car" = "Car", "suv" = "SUV")
     */
    abstract class Vechicle {
        private $make;
        private $model;
        private $numberOfDoors;
    
        // getters and setters //
    }
    
    class Truck extends Vehicle {
        private $offRoadPackage;
        private $bedSize;
    
        // getters and setters //
    }
    
    class Car extends Vehicle {
        private $bodyType;
    }
    
    class SUV extends Vehicle {
        // no additional fields //
    }
    
    然后我的表单类型如下所示:

    class VehicleType extends AbstractType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder
                ->add('make')
                ->add('model')
                ->add('numberOfDoors');
        }
    
        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => 'MyBundle\Entity\Vehicle'
            ));
        }
    }
    
    class TruckType extends VehicleType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            parent::buildForm($builder, $options);
            $builder
                ->add('offRoadPackage')
                ->add('bedSize');
        }
    
        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => 'MyBundle\Entity\Truck'
            ));
        }
    }
    
    class CarType extends VehicleType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            parent::buildForm($builder, $options);
            $builder
                ->add('bodyType')
        }
    
        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => 'MyBundle\Entity\Car'
            ));
        }
    }
    
    class SUVType extends VehicleType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            parent::buildForm($builder, $options);
        }
    
        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => 'MyBundle\Entity\SUV'
            ));
        }
    }
    

    这将是一个有点长的一个,但请容忍我。这个想法的要点是在数组中处理表单。创建一个类型列表,通过迭代来构建实际的表单对象。这样,如果希望添加更多的表单类型,您只需编辑表单类型列表

    在模板中,您迭代所有表单以呈现它们,并将它们包装在可以隐藏的div中。接下来,您可以添加一个select元素,该元素控制一段javascript,显示/隐藏用户选择的类型的形式

    发布后,您可以测试操作是否已发布到,并重复表单,以检查其中哪一个已提交并适当处理

    以下是未经测试的粗略代码段:

    控制员/行动:

    模板:

    <select id="types">
        {% for type in types|keys %}
            <option value="vehicle_type_{{ loop.index }}">{{ type }}</option>
        {% endfor %}
    </select>
    {% for form in forms %}
        <div class="form hidden" id="vehicle_type_{{ loop.index }}">
            {{ form_start(form) }}
            {{ form_widget(form) }}
            {{ form_end(form) }}
        </div>
    {% endfor %}
    
    
    {%用于类型中的类型|键%}
    {{type}}
    {%endfor%}
    {表格%中的表格为%}
    {{form_start(form)}}
    {{form_widget(form)}
    {{form_end(form)}}
    {%endfor%}
    
    最后是控制显示/隐藏表单的javascript片段:

    
    //在“选择”“更改”“隐藏除刚才选择的窗体以外的所有窗体”
    $('#types')。在('change',function(){
    $('.form').addClass('hidden');
    $('#'+$(this.val()).removeClass('hidden');
    });
    
    太棒了。我在你的指导下成功了。谢谢没问题,很高兴我能帮上忙:)@Telexen
    <select id="types">
        {% for type in types|keys %}
            <option value="vehicle_type_{{ loop.index }}">{{ type }}</option>
        {% endfor %}
    </select>
    {% for form in forms %}
        <div class="form hidden" id="vehicle_type_{{ loop.index }}">
            {{ form_start(form) }}
            {{ form_widget(form) }}
            {{ form_end(form) }}
        </div>
    {% endfor %}