【发布时间】:2020-11-04 11:40:26
【问题描述】:
我的问题没那么简单,我会尽量总结。
假设我有一个实体 Vehicle,它与实体 Engine 相关。 Engine 实体是一种抽象类型,由 2 个类实现:ElectricEngine 和 GasEngine。
我想为 Vehicle 创建一个表单,该表单将创建一个车辆及其引擎类型,但我无法添加绑定了 Engine 实体的 CustomType 字段,因为它是一个抽象实体。所以我需要用 ElectricEngine 或 GasEngine 动态添加一个 CustomType 字段。这是VehicleType.php:
// App\Form\VechicleType::buildForm
$builder
->add('wheels', IntegerType::class)
->add('type', ChoiceType::class, [
'choices' => [
'ElectricEngine' => 1,
'GasEngine' => 2
],
'mapped' => false
])
因此,当用户提交此表单时,我想取消提交并添加我的 ElectricEngineType 或 GasEngineType 字段,具体取决于我的用户选择的字段。
现在,这是我的解决方案:我在构建 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