我有一个包含 3 个相关字段的表单:
制造商 -> 制造商产品组 -> 制造商产品系列
所以我想选择一个制造商,基于制造商的产品组和基于产品组的产品系列。
有一个关于如何处理这种动态表单的 CookBook 条目,它很容易为 ManufacturerProductGroup 工作。问题是 ManufacturerProductSeries 依赖于另一个动态表单/字段。
问题是,我无法在闭包中添加侦听器,因为我只能访问 FormInterface 而不能再访问 FormBuilderInterface。
我不能像在 PRE_SET_DATA 侦听器中那样只使用一个侦听器来做到这一点,因为随后将提交表单,这会阻止任何修改。我要么需要一种动态添加侦听器的方法,要么只更新 POST_SUBMIT 侦听器中的数据,而不是替换整个字段/表单。
这是给出错误的代码,因为我正在向不存在的表单字段添加侦听器(manufacturerProductGroup 仅在 pre_set_data 事件之后可用)
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('manufacturer', 'entity', array('class' => 'ArticleBundle:manufacturer', 'empty_value' => false));
$manufacturerProductGroupModifier = function(FormInterface $form, Manufacturer $manufacturer)
{
$manufacturerProductGroups = $this->em->getRepository('ArticleBundle:ManufacturerProductGroup')
->findAvailableByManufacturer($manufacturer);
$form->add(
'manufacturerProductGroup',
'entity',
array(
'class' => 'ArticleBundle:ManufacturerProductGroup',
'empty_value' => '',
'choices' => $manufacturerProductGroups
)
);
};
$manufacturerProductSeriesModifier = function(FormInterface $form, ManufacturerProductGroup $manufacturerProductGroup)
{
$manufacturerProductSeries = $this->em->getRepository('ArticleBundle:ManufacturerProductSeries')
->findAvailableByManufacturerProductGroup($manufacturerProductGroup);
$form->add(
'manufacturerProductSeries',
'entity',
array(
'class' => 'ArticleBundle:ManufacturerProductSeries',
'empty_value' => '',
'choices' => $manufacturerProductSeries
)
);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) use ($manufacturerProductGroupModifier, $manufacturerProductSeriesModifier) {
/** @var $article Article */
$article = $event->getData();
$manufacturerProductGroupModifier($event->getForm(), $article->getManufacturer());
$manufacturerProductSeriesModifier($event->getForm(), $article->getManufacturerProductGroup());
}
);
$builder->get('manufacturer')->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($manufacturerProductGroupModifier) {
$manufacturer = $event->getForm()->getData();
$manufacturerProductGroupModifier($event->getForm()->getParent(), $manufacturer);
}
);
$builder->get('manufacturerProductGroup')->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($manufacturerProductSeriesModifier) {
$manufacturerProductGroup = $event->getForm()->getData();
$manufacturerProductSeriesModifier($event->getForm()->getParent(), $manufacturerProductGroup);
}
);
}