【问题标题】:Symfony 5.1 - Dynamically add a CustomType field before submittingSymfony 5.1 - 在提交之前动态添加一个 CustomType 字段
【发布时间】:2020-11-04 11:40:26
【问题描述】:

我的问题没那么简单,我会尽量总结。

假设我有一个实体 Vehicle,它与实体 Engine 相关。 Engine 实体是一种抽象类型,由 2 个类实现:ElectricEngineGasEngine

我想为 Vehicle 创建一个表单,该表单将创建一个车辆及其引擎类型,但我无法添加绑定了 Engine 实体的 CustomType 字段,因为它是一个抽象实体。所以我需要用 ElectricEngineGasEngine 动态添加一个 CustomType 字段。这是VehicleType.php

// App\Form\VechicleType::buildForm
$builder
        ->add('wheels', IntegerType::class)
        ->add('type', ChoiceType::class, [
            'choices' => [
                'ElectricEngine' => 1,
                'GasEngine' => 2
            ],
            'mapped' => false
        ])

因此,当用户提交此表单时,我想取消提交并添加我的 ElectricEngineTypeGasEngineType 字段,具体取决于我的用户选择的字段。

现在,这是我的解决方案:我在构建 VehicleForm 时使用 POST_SUBMIT 事件。我正在查看用户选择了哪种类型,并且正在添加匹配的字段。然后我添加一个错误以取消提交,以便再次呈现表单,但使用新字段。

// App\Form\VehicleTypeForm::buildForm
// After building form ...
$builder->get('type')->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event){
        $form = $event->getForm()->getParent();

        if($form->get('type')->getData() != null) {
            switch ($form->get('type')->getData()) {
                case 1:
                    $form->add('engine', ElectrineEngine::class);
                    $form->remove('type');
                    break;
                case 2:
                    $form->add('engine', GasEngine::class);
                    $form->remove('type');
                    break;
                default:
                    // Do Nothing
            }
            // Adding Error so the form is not submitted
            $form->addError(new FormError('Adding engine field'));
        }
    });

通过添加错误,表单不再有效,因此将再次呈现。 如果有人和我有同样的问题,这是一个解决方案。

但我认为它不是最好的,因为我在表单中添加了一个错误,并且没有错误。我希望有更好的方法来实现它,但我不知道该怎么做。

我考虑过使用https://github.com/craue/CraueFormFlowBundle 来使用多个步骤,但这会添加电动发动机和燃气发动机步骤,我们将不得不跳过一个。我认为这不是最好的主意,因为在我的实际项目中(当然,我并没有用车辆和引擎开发任何东西)我有 3 个抽象实体的孩子,而且还会有更多。也许这个捆绑包是最好的主意,但我不太确定:/

【问题讨论】:

    标签: php forms symfony types symfony-forms


    【解决方案1】:

    我找到了更好的解决方案。对于有同样问题的人,这是给你的。

    与其做一个通用的表格并对其进行调整,最好的方法是拥有许多表格并每次添加共同的部分。是的,我很笨,我没想到。

    以车辆为例:我们将有一个带有通用字段的 VehicleForm。这里是 ElectricEngineForm :

    // App\Form\ElectricEngineForm
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $genericType = new VehicleType();
        $genericType->buildForm($builder, $options);
        $builder->add('engine', ElectricEngineType::class);
    }
    
    
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Vehicle::class
        ]);
    }
    

    ElectricEngineType 是包含 ElectricEngine 特性的表单。您还必须创建 GasEngineForm 和 GasEngineType。然后根据用户所走的路线渲染你想要的那个。

    如果用户在 /vehicle/add/electric,那么我们渲染 ElectricEngineForm,否则如果他在 /vehicle/add/gas,那么我们渲染 GasEngineForm。

    如果您愿意,您可以使用我认为的其他方法构建通用表单。也许是静态方法,否则我不知道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 2012-05-26
      • 2018-10-09
      • 2014-06-23
      • 1970-01-01
      • 2016-06-06
      • 1970-01-01
      相关资源
      最近更新 更多