【发布时间】:2015-06-07 13:11:43
【问题描述】:
我有一个带有两个分层动态字段的 Symfony2 表单。第一层使用表单事件实现记录的方式没有问题:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms
然后是第三个字段,它依赖于第二个字段,它已经是一个动态字段。
为了演示这个问题,这里是我的剥离代码:
<?php
class ServiceeventType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('park', 'entity', array(
'class' => 'AppBundle:Park',
'property' => 'identifyingName',
'label' => 'Park',
'required' => true,
'invalid_message' => 'Choose a Park',
'placeholder' => 'Please choose',
))
// just a placeholder for the $builder->get('facility')->addEventListener to have something to bind to
// I'm aware, that this is just a symptom of my problem
->add('facility', 'choice', array(
'choices' => array(),
'expanded' => true,
'multiple' => false,
'label' => 'Facility',
'required' => false,
'invalid_message' => 'Choose a Park first',
'placeholder' => 'Please choose a Park first',
))
// other fields
;
$formModifierPark = function (FormInterface $form, Park $park = null) {
// overwrite the facility field with the desired entity type
$form->add('facility', 'entity', array(
'class' => 'AppBundle:Facility',
'property' => 'identifyingName',
'choices' => null === $park ? array() : $park->getFacilities(),
'label' => 'Facility',
'required' => true,
'invalid_message' => 'Choose a Facility',
'placeholder' => null === $park ? 'Please choose a Park first' : 'Please choose',
));
};
$formModifierFacility = function (FormInterface $form, Facility $facility = null) {
$form->add('facilityStatuscode', 'entity', array(
'class' => 'AppBundle:FacilityStatuscode',
'property' => 'identifyingName',
'choices' => null === $facility ? array() : $facility->getFacilityStatuscodeType()->getFacilityStatuscodes(),
'label' => 'Statuscode',
'required' => null === $facility ? false : true,
'invalid_message' => 'Choose a Statuscode',
'placeholder' => null === $facility ? 'Please choose a Facility first' : 'Please choose',
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifierPark) {
$formModifierPark($event->getForm(), $event->getData()->getPark());
}
);
$builder->get('park')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifierPark) {
$formModifierPark($event->getForm()->getParent(), $event->getForm()->getData());
}
);
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifierFacility) {
$formModifierFacility($event->getForm(), $event->getData()->getFacility());
}
);
$builder->get('facility')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifierFacility) {
$formModifierFacility($event->getForm()->getParent(), $event->getForm()->getData());
}
);
}
// more code
}
现在的问题是:
用$builder->get('facility')->addEventListener(FormEvents::POST_SUBMIT,… 设置的事件监听器此时丢失,设施字段被另一个事件监听器覆盖。
我尝试了几种解决方法,但事实证明,一旦构建器准备好(即添加到事件侦听器中时),表单字段选项不能被覆盖,并且表单稍后添加的字段不接受新的事件侦听器。
我真的必须解决这个问题。我错过了什么吗? Symfony2 的表单引擎是否无法处理两个分层的动态表单字段依赖关系?
有什么建议吗?
【问题讨论】:
-
这就是你要找的东西 - showmethecode.es/php/symfony/symfony2-4-dependent-forms ?
-
谢谢!看起来这就是我的解决方案,
addEventSubscriber而不是addEventListener,嗯。我会在复活节假期后回到办公室时看看它。