我有一个包含3个依赖字段的表单:
制造商 – > ManufacturerProductGroup – > ManufacturerProductSeries
所以我想选择一个制造商,基于制造商产品组和产品系列产品组.
有关于如何处理这种动态形式的CookBook条目
它很容易为ManufacturerProductGroup工作.问题是
ManufacturerProductSeries依赖于另一个动态表单/字段.
问题是,我不能在闭包中添加一个Listener,因为我只有
对FormBuilderInterface的访问不再是FormInterface.
自从表单以来,我只能在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',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',array( 'class' => 'ArticleBundle:ManufacturerProductSeries','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); } ); }
解决方法
我用以下代码解决了这个问题:
$addManufacturerProductSeries = function (FormEvent $event) { $form = $event->getForm()->getParent(); $manufacturerProductGroup = $event->getData(); $form->add( 'manufacturerProductSeries',array( 'auto_initialize' => false,'class' => 'ArticleBundle:ManufacturerProductSeries','query_builder' => function (ManufacturerProductSeriesRepository $repository) use ($manufacturerProductGroup) { return $repository->findAvailableByManufacturerProductGroupQueryBuilder($manufacturerProductGroup); },) ); }; $addManufacturerProductGroup = function (FormEvent $event) use ($factory,$addManufacturerProductSeries) { $form = $event->getForm()->getParent(); $manufacturer = $event->getData(); $fieldBuilder = $factory->createNamedBuilder( 'manufacturerProductGroup',null,'class' => 'ArticleBundle:ManufacturerProductGroup','query_builder' => function (ManufacturerProductGroupRepository $repository) use ($manufacturer) { return $repository->findAvailableByManufacturerQueryBuilder($manufacturer); },) ); $fieldBuilder->addEventListener(FormEvents::POST_SET_DATA,$addManufacturerProductSeries); $fieldBuilder->addEventListener(FormEvents::POST_SUBMIT,$addManufacturerProductSeries); $form->add($fieldBuilder->getForm()); }; $builder->get('manufacturer')->addEventListener(FormEvents::POST_SET_DATA,$addManufacturerProductGroup); $builder->get('manufacturer')->addEventListener(FormEvents::POST_SUBMIT,$addManufacturerProductGroup);