Symfony的:形式与继承的类(Symfony: Forms with inherited cla

2019-11-04 06:36发布

我试图找出如何使用与Symfony的(2.8.6)继承类类型时处理形式。

我已经创造了什么,我想在下面做了[很]简单的例子情况。 有与它的问题,但它只是说明我的问题。

  1. 我怎样才能提供的一种形式从控制器将树枝模板,以便有可能选择什么“型”(鉴别)字段应该使用? 我应该简单地创建另一个变量,如在每个类的硬编码“型”?
  2. 一旦提交表单时,我怎么能弄清楚哪些类应该在控制器中使用,在任何一个“新”或“编辑”行为? 我已经试过拔除其拉出ParameterBag,创造适当的实体和形式,然后使用$形式 - >的handleRequest($请求); ...但它似乎并不时有可能属于另一种类型的额外下地干活。

如果有人甚至可以点我到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'
        ));
    }
}

Answer 1:

这将是一个有点冗长的一个,但我承担。 这一理念的要点是,你面对一个数组的形式。 您创建的,您遍历构建实际表单对象类型的列表。 这样,您编辑的唯一的事情是,如果你想添加更多表单类型的列表。

在您的模板,你遍历所有的形式来呈现他们,你可以隐藏一个div包装他们。 接着可以添加控制片的JavaScript表示/隐藏用户选择的类型的形式的选择元件。

sbumission后,您可以测试是否动作已经被发布到并重申形式,以检查它们中的哪一个已提交并妥善处理这个问题。

下面是一个未经测试的原油代码片段:

控制器/动作:

 class SomeController { public function addAction() { $types = [ 'Form1' => Form1::class, 'Form2' => Form2::class, 'Form3' => Form3::class, ]; // create the forms based on the types indicated in the types arary $forms = []; foreach ($types as $type) { $forms[] = $this->createForm($type); } if ($request->isMethod('POST')) { foreach ($forms as $form) { $form->handleRequest($request); if (!$form->isSubmitted()) continue; // no need to validate a form that isn't submitted if ($form->isValid()) { // handle the form of your type break; // stop processing as we found the form we have to deal with } } } $views = []; foreach ($forms as $form) { $views = $form->createView(); } $this->render('template.html.twig', ['forms' => $views, 'types' => $types]); } } 

模板:

<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 %}

最后是一段JavaScript代码控制显示/隐藏什么形式的:

<script>
    // On select change hide all forms except for the on that was just selected
    $('#types').on('change', function () {
        $('.form').addClass('hidden');
        $('#' + $(this).val()).removeClass('hidden');
    });
</script>


文章来源: Symfony: Forms with inherited classes