如何使用symfony动态修改表单(嵌套表单)?

时间:2017-10-03 11:16:07

标签: forms symfony doctrine

我从这里跟随我的例子How to fill the dropdown list dynamically in symfony? (select the cities of the region)

我尝试制作嵌套表单,在表单中嵌入表单集合。我有buildForm的问题。

就我而言,我正在尝试为雇主(雇主)实体的公司(企业)实体选择该地区的城市。

我在添加实体时遇到问题,在企业版的情况下我也遇到了问题。

添加雇主(雇主)实体时:(我无法显示添加表单)

此示例适用于某些实体(一种简单的形式,而不是嵌套)。

但是当我用Employer实体尝试它时,我收到了这个错误:

  

在null

上调用成员函数getVille()

堆栈跟踪:

  

FatalThrowableError   Symfony \ Component \ Debug \ Exception \ FatalThrowableError:调用a   成员函数getVille()on null

     

在src \ GE \ CandidatBundle \ Form \ EntrepriseType.php:159 at   GE \ CandidatBundle \表格\ EntrepriseType-> GE \ CandidatBundle \表格{闭合}(对象(FormEvent),   ' form.pre_set_data',object(EventDispatcher))at   call_user_func(object(Closure),object(FormEvent),   ' form.pre_set_data',object(EventDispatcher))        (供应商\ symfony的\ symfony的\ SRC \的Symfony \元器件\此事件\ EventDispatcher.php:212)   在   的Symfony \组件\此事件\ EventDispatcher-> doDispatch(阵列(对象(封闭)),   ' form.pre_set_data',object(FormEvent))        (供应商\ symfony的\ symfony的\ SRC \的Symfony \元器件\此事件\ EventDispatcher.php:44)   在   的Symfony \组件\此事件\ EventDispatcher->调度(' form.pre_set_data&#39 ;,   对象(FormEvent))        (供应商\ symfony的\ symfony的\ SRC \的Symfony \元器件\此事件\ ImmutableEventDispatcher.php:43)   在   的Symfony \组件\此事件\ ImmutableEventDispatcher->调度(' form.pre_set_data&#39 ;,   对象(FormEvent))        (vendor \ symfony \ symfony \ src \ Symfony \ Component \ Form \ Form.php:341)在Symfony \ Component \ Form \ Form-> setData(null)        (供应商\ symfony的\ symfony的\ SRC \的Symfony \元器件\表格\扩展\核心\ DataMapper的\ PropertyPathMapper.php:57)   在   的Symfony \组件\表格\扩展\核心\ DataMapper的\ PropertyPathMapper-> mapDataToForms(对象(Employeur),   对象(RecursiveIteratorIterator))        (vendor \ symfony \ symfony \ src \ Symfony \ Component \ Form \ Form.php:385)在Symfony \ Component \ Form \ Form-> setData(object(Employeur))        (vendor \ symfony \ symfony \ src \ Symfony \ Component \ Form \ Form.php:489)在Symfony \ Component \ Form \ Form-> initialize()        (供应商\ symfony的\ symfony的\ SRC \的Symfony \元器件\表格\ FormBuilder.php:226)   在Symfony \ Component \ Form \ FormBuilder-> getForm()        (供应商\ symfony的\ symfony的\ SRC \的Symfony \元器件\表格\ FormFactory.php:30)   在   的Symfony \组件\表格\ FormFactory->创建(' GE \ CandidatBundle \表格\ EmployeurType&#39 ;,   对象(Employeur),array())        (供应商\ symfony的\ symfony的\ SRC \的Symfony \捆绑\ FrameworkBundle \控制器\ ControllerTrait.php:331)   在   的Symfony \捆绑\ FrameworkBundle \控制器\控制器 - >的CreateForm(' GE \ CandidatBundle \表格\ EmployeurType&#39 ;,   对象(Employeur))        (src \ GE \ CandidatBundle \ Controller \ EmployeurController.php:44)at   GE \ CandidatBundle \控制器\ EmployeurController-> newAction(对象(请求))   at call_user_func_array(array(object(EmployeurController),   ' newAction'),array(object(Request)))

雇主实体:

class Employeur extends Utilisateur
{
    /**
     * @ORM\OneToOne(targetEntity="GE\CandidatBundle\Entity\Entreprise", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    protected $entreprise;
}

EntrepriseType:

    $builder
            ->add('raisonSocial')
            ->add('region', EntityType::class, [
                'label' => 'Region *',
                'label_attr' => [
                    "class" => "smaller lighter blue",
                    "style" => "font-size: 21px;",
                ],
                'placeholder' => 'Sélectionnez une region',
                'class' => 'GECandidatBundle:Region',
                'choice_label' => 'nom',
                'multiple' => false,
                'query_builder' => function (RegionRepository $repository) {
                    return $repository->getListeRegion();
                }
            ])
            ->add('ville');
$formModifier = function (FormInterface $form, Region $region = null) {
            $villes = null === $region ? array() : $region->getVilles();
            $form->add('ville', EntityType::class, array(
                'label' => 'Ville *',
                'label_attr' => [
                    "class" => "smaller lighter blue",
                    "style" => "font-size: 21px;",
                ],
                'placeholder' => 'Sélectionnez une ville',
                'class' => 'GECandidatBundle:Ville',
                'choice_label' => 'nom',
                'choices' => $villes,
                'multiple' => false,
                'expanded' => false,
            ));
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                $data = $event->getData();
                $formModifier($event->getForm(), $data->getVille());
            }
        );

        $builder->get('region')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                $region = $event->getForm()->getData();
                $formModifier($event->getForm()->getParent(), $region);
            }
        );

我的问题出在这一行:

  

$ formModifier($ event-> getForm(),$ data-> getVille());

为什么我的例子之前运作良好,现在已经不再有效了?

修改公司(Entreprise)实体时:(我无法显示编辑表单)

  

类型错误:参数2传递给   GE \ CandidatBundle \表格\ EntrepriseType :: GE \ CandidatBundle \表格{闭合}()   必须是GE \ CandidatBundle \ Entity \ Region的实例或null,   Proxies的实例_CG __ \ GE \ CandidatBundle \ Entity \ Ville给出,   呼唤   C:\ XAMPP \ htdocs中\ GestionEmploi的\ src \ GE \ CandidatBundle \表格\ EntrepriseType.php   在第159行

我对此行有疑问:

  

$ formModifier = function(FormInterface $ form,Region $ region = null)

也许我的问题在于EmployeurType:

$builder
->add('nom')
->add('prenom')
...
->add('entreprise', EntrepriseType::class);

1 个答案:

答案 0 :(得分:0)

在PRE_DATA-SET事件

$event->getData() // can be null

所以在调用$ data-> getVille()之前检查$ data!= null的代码

$data = $event->getData(); 
$ville = null; 
if ($data != null) 
    $ville = $event->getData()->getVille();
$formModifier($event->getForm(), $ville);