Symfony - 动态下拉列表仅在编辑时才起作用 [英] Symfony - dynamic drop down lists not working only when editing

查看:229
本文介绍了Symfony - 动态下拉列表仅在编辑时才起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我是法国人,所以我希望我的英语不是很糟糕^^'我有Symfony3的问题,我不知道如何解决它。



我有一个包含3个下拉列表的表单。主题2相关:机构和中心。一个机构可以有几个中心。因此,当我选择一家代理机构时,
的中心列表会更新。第三个下拉列表是Category。它们都与具有相同名称的实体相关。



要用Symfony做到这一点,我遵循官方文档: http://symfony.com/doc/3.0/form/dynamic_form_modification.html#form-events-submitted -data



在创建表单中一切正常。但是,当我使用相同的表单进行编辑时,使用相同的下拉列表,ajax请求不起作用:/
它告诉我该类别(在第三个下拉列表中)设置为空。
$ b


未捕获的PHP异常
Symfony \组件\PropertyAccess\Exception\InvalidArgumentException:
期望的参数类型EDVS \SinistreBundle \Entity \Categorie,
NULL给出在
C:\wamp\www\SinistraV2\vendor\symfony\symfony\\ \\ src\Symfony\Component\PropertyAccess\PropertyAccessor.php
line 254


它没有任何关系与我的2人下降名单,但显然,这是问题。更清楚的是,当我在我的编辑表单中选择代理商时,会触发此错误。这样做发起了一个Ajax请求,它应该用中心更新列表,但事实并非如此。



当我查看堆栈跟踪时,传递给参数setCategory()函数为空。



我在控制器和formType文件中验证过,我的类别不是null。下拉列表中填充了可用的类别,并设置为数据库中保留的类别。



这里是我的formType文件:

  class SinistreType extends AbstractType 
{
/ **
* @param FormBuilderInterface $ builder
* @param array $ options
* /
public function buildForm(FormBuilderInterface $ builder,array $ options)
{
//Récupérationdes sous-types,passésenparamètrevia les options du form(voir aussi function configureOptions plus bas)
$ sousTypeSinistre = $ options ['sousTypeSinistre'];
$ em = $ options ['em'];

uilder
[...]
- > add('categorie',EntityType :: class,array(
'class'=>' EDVSSinistreBundle:Categorie',
'placeholder'=>'Choisir unecatégorie',
'choice_label'=>'intituleCat',
))
[...]
- > add('save',SubmitType :: class);

;
$ b $ / **
* Listedéroulantedynamique
* Selon l'agencesélectionnée,la liste de centre correspondant change
* /
$ centresModifier = function (FormInterface $ form,Agence $ agence = null){
/ **
* Si l'agencepasséeen param est null,$ centersreçoitun tableau vide,
* sinon $ centers prend如果你想让你的生活变得更加美好, array():$ agence-> getCentres();

// Ajout,dans le formulaire,de la listedéroulantecontenant les centrerécupérésprécédemment
$ form-> add('center',EntityType :: class,array(
'class'=>'EDVSAgenceCentreBundle:Center',
'placeholder'=>'Choisir un center',
'choices'=> $ centers,
'choice_label'= >'nom',
));
};

//演示文稿的构建时间
$ builder-> addEventListener(FormEvents :: PRE_SET_DATA,function(FormEvent $ event)use($ centresModifier,$ em){
$ data = $ event-> getData(); //EntitéSinistre
$ form = $ event-> getForm();

// Dans le cas d ($ data-> getCentreUtilise()){
//Récupérationdu centre& de l'agence par rapport aucentreUtilisé&àl' agenceUtiliséeliésau dossier en cours de modification
$ center = $ em-> getRepository('EDVSAgenceCentreBundle:Center') - > getCentreByNom($ data-> getCentreUtilise() - > getNom()); $ getAccessBundle() - > getAmptyUtilisee() - > getNom(); getNom() ));

//Sélectionde l'agence& du centre dans les listesdéroulantescorrespondantes
$ data-> setCentre($ center [0]);
$ data-> setAgence($ agence [0]);

// Affichage de la liste des agences disponibles& ($ form,$ data-> getAgence()); ($ form),$ data-> getAgence());
} else {// Dans le cas d'unecréation(donnéesvides)
$ centresModifier
}
});

//获取('agence') - > addEventListener(FormEvents:
$ b)//获取('agence') - > addEventListener(FormEvents: :POST_SUBMIT,函数(FormEvent $ event)使用($ centresModifier){
$ form = $ event-> getForm();
$ agence = $ form-> getData();

$ centresModifier($ form-> getParent(),$ agence);
});

$ b $ **
* @param OptionsResolver $ resolver
* /
public function configureOptions(OptionsResolver $ resolver)
{
$ resolver-> setDefaults(array(
'data_class'=>'EDVS\SinistreBundle\Entity\Sinistre',
'sousTypeSinistre'=> null,//Déclaration duparamètretypeSinistrepour qu'il puisseêtrereconnu comme option(transfert du param controller vers form)
'em'=> null,//同上
));
}

}

javascript部分:

  $(document).ready(function(){
var agence = $('# sinistre_edit_agence');

/ *实现对话中心的实现* /
agence.change(function(){
//动画费用en cours
toggleLoading();

var form = $(this).closest('form');
var data = {};
data [agence.attr('name')] = agence.val();

$ .ajax({
url:form.attr('action'),
type :form.attr('method'),
data:data,
success:function(html){
$('#sinistre_edit_centre')。replaceWith(
$(html ).find('#sinistre_edit_centre')
);
toggleLoading();
},
错误:函数(错误){
console.error(error);
toggleLoading();
}
});
});
});

这里似乎是同样的问题: Symfony 2:动态表单事件仅在编辑时返回InvalidArgumentException



但是没有答案,我真的不知道我做错了什么。我想我没有正确使用表单事件,这对我来说是全新的。



我希望在这里能找到一些帮助,谢谢!

解决方案

好的,我找到了一个解决方案,显然问题出在我的javascript中。对于Ajax请求中的属性data,我必须传递下拉列表Category的值。然后,当我运行Ajax请求时,它工作正常。如果我不这样做,就像我在第一条消息中说的那样,Ajax请求因为Category值设置为null而失败。我的新javascript:

  $(document).ready(function(){
var agence = $('#sinistre_edit_agence');
$ b $ * / * b $ b agence.change(function(){
//动画Chargement en cours
toggleLoading();

var form = $(this).closest('form');
var data = {};
data [agence.attr ('name')] = agence.val();
data [categorie.attr('name')] = categorie.val(); // FIX:类别值

$ .ajax({
url:form.attr('action'),
type:form.attr('method'),
data:data,//现在,包含我的 Agence值和Category值
success:function(html){
$('#sinistre_edit_centre')。replaceWith(
$(html).find('#sinistre_edit_centre')
);
toggleLoading();
},
错误:函数(错误){
console.error(error);
toggleLoading();
}
});
});

});



我必须承认我真的不明白为什么第三个下拉列表与我的其他2个相关的下拉列表无关,是问题所在!


First of all, I'm French, so I hope my english is not so bad ^^' I have a problem with Symfony3 and I don't know how to resolve it.

I have a form with 3 drop down lists. 2 of theme are related : Agency and Center. One agency can have several centers. So, when I select an agency, the list with the centers is updated. The third drop down list is Category. They're all related to entities with the same name.

To do that with Symfony, I followed the official documentation : http://symfony.com/doc/3.0/form/dynamic_form_modification.html#form-events-submitted-data

Everything works fine in the creation form. But when I use the same form for editing, with the same drop down lists, the ajax request doesn't work :/ It says to me that the category (in the third drop down list) is set to null.

Uncaught PHP Exception Symfony\Component\PropertyAccess\Exception\InvalidArgumentException: "Expected argument of type "EDVS\SinistreBundle\Entity\Categorie", "NULL" given" at C:\wamp\www\SinistraV2\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php line 254

It has nothing to do with my 2 others drop down lists but apparently, this is the problem. To be clearer, this error is triggered when I select an agency in my editing form. Doing this launched an Ajax request and it's supposed to update the list with the centers but it's not the case.

When I look at the stack trace, the parameter passed in the setCategory() function is null.

I verified in the controller and the formType file, my category isn't null. The drop down list is filled with the available categories and set to the category which is persisted in the database.

Here, my "formType" file :

    class SinistreType extends AbstractType
    {
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            // Récupération des sous-types, passés en paramètre via les options du form (voir aussi function configureOptions plus bas)
            $sousTypeSinistre = $options['sousTypeSinistre'];
            $em = $options['em'];

            $builder
            [...]
                ->add('categorie', EntityType::class, array(
                    'class'         => 'EDVSSinistreBundle:Categorie',
                    'placeholder'   => 'Choisir une catégorie',
                    'choice_label'  => 'intituleCat',
                ))
                [...]
                ->add('save', SubmitType::class);

            ;

            /**
             * Liste déroulante dynamique
             * Selon l'agence sélectionnée, la liste de centres correspondant change
             */
            $centresModifier = function (FormInterface $form, Agence $agence = null) {
                /**
                 * Si l'agence passée en param est null, $centres reçoit un tableau vide,
                 * sinon $centres prend comme valeur la liste des centres rattachés à l'agence
                 */
                $centres = null === $agence ? array() : $agence->getCentres();

                // Ajout, dans le formulaire, de la liste déroulante contenant les centres récupérés précédemment
                $form->add('centre', EntityType::class, array(
                    'class'         => 'EDVSAgenceCentreBundle:Centre',
                    'placeholder'   => 'Choisir un centre',
                    'choices'       => $centres,
                    'choice_label'  => 'nom',
                ));
            };

            // Evénement appelé au moment de la construction du formulaire
            $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($centresModifier, $em) {
                $data = $event->getData(); // Entité Sinistre
                $form = $event->getForm();

                // Dans le cas d'une modification (données provenant de la BDD)
                if ($data->getCentreUtilise()) {
                    // Récupération du centre & de l'agence par rapport au centreUtilisé & à l'agenceUtilisée liés au dossier en cours de modification
                    $centre = $em->getRepository('EDVSAgenceCentreBundle:Centre')->getCentreByNom($data->getCentreUtilise()->getNom());
                    $agence = $em->getRepository('EDVSAgenceCentreBundle:Agence')->getAgenceByNom($data->getCentreUtilise()->getAgenceUtilisee()->getNom());

                    // Sélection de l'agence & du centre dans les listes déroulantes correspondantes
                    $data->setCentre($centre[0]);
                    $data->setAgence($agence[0]);

                    // Affichage de la liste des agences disponibles & des centres correspondants
                    $centresModifier($form, $data->getAgence());
                } else { // Dans le cas d'une création (données vides)
                    $centresModifier($form, $data->getAgence());
                }
            });

            // Evénement appelé juste après que le formulaire ait été validé, concerne le champ "agence" seulement
            $builder->get('agence')->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) use ($centresModifier) {
            $form = $event->getForm();
            $agence = $form->getData();

            $centresModifier($form->getParent(), $agence);
        });
}

/**
 * @param OptionsResolver $resolver
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class'        => 'EDVS\SinistreBundle\Entity\Sinistre',
        'sousTypeSinistre'  => null, // Déclaration du paramètre "typeSinistre" pour qu'il puisse être reconnu comme option (transfert du param controller vers form)
        'em'                => null, // Idem
    ));
}

}

The javascript part :

$(document).ready(function() {
    var agence = $('#sinistre_edit_agence');

    /* Actualisation de la liste déroulante des centres en fonction de l'agence sélectionnée */
    agence.change(function() {
        // Animation "Chargement en cours"
        toggleLoading();

        var form = $(this).closest('form');
        var data = {};
        data[agence.attr('name')] = agence.val();

        $.ajax({
            url : form.attr('action'),
            type: form.attr('method'),
            data : data,
            success: function(html) {
                $('#sinistre_edit_centre').replaceWith(
                    $(html).find('#sinistre_edit_centre')
                );
                toggleLoading();
            },
            error: function(error) {
                console.error(error);
                toggleLoading();
            }
        });
    });
});

It seems to be the same problem here : Symfony 2: Dynamic Form Event returns InvalidArgumentException only when editing

But there's no answer and I really don't know what I'm doing wrong. I think I'm not using the form events correctly, it's completely new to me.

I hope I'll find some help here, thanks in advance !

解决方案

Ok, so I found a solution, apparently the problem was in my javascript. For the attribute "data" in the Ajax request, I have to pass the value of the drop down list "Category". Then, when I run the Ajax request, it works fine. If I don't do that, like I said in my first message, the Ajax request fails because the "Category" value is set to null.

My new javascript :

$(document).ready(function() {
var agence = $('#sinistre_edit_agence');

/* Actualisation de la liste déroulante des centres en fonction de l'agence sélectionnée */
agence.change(function() {
    // Animation "Chargement en cours"
    toggleLoading();

    var form = $(this).closest('form');
    var data = {};
    data[agence.attr('name')] = agence.val();
    data[categorie.attr('name')] = categorie.val(); // FIX : the category value

    $.ajax({
        url : form.attr('action'),
        type: form.attr('method'),
        data : data, // Now, contains my "Agence" value and "Category" value
        success: function(html) {
            $('#sinistre_edit_centre').replaceWith(
                $(html).find('#sinistre_edit_centre')
            );
            toggleLoading();
        },
        error: function(error) {
            console.error(error);
            toggleLoading();
        }
    });
});

});

I have to admit that I don't really understand why the third drop down list, which has nothing to do with my 2 others related drop down lists, was the problem !

这篇关于Symfony - 动态下拉列表仅在编辑时才起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆