在第二个 ChoiceType 中 select 一个 gouvernorat 之后加载 choiceType 中的城市

load cities in choiceType after select one gouvernorat in a second ChoiceType

我有两个实体与 Gouvernorat -> Villes 有关联。

这是 Gouvernorat 实体:

class Gouvernorat
    {
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=100, nullable=false)
     */
    private $name;
    /**
     * @ORM\OneToMany(targetEntity="EntiteBundle\Entity\Ville", mappedBy="idGouvernorat")
     */
    private $villes;
    //getters & setters & constructor
}

这是城市实体:

class Ville
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=200, nullable=false)
 */
private $name;

/**
 * @var \Gouvernorat
 *
 * @ORM\ManyToOne(targetEntity="EntiteBundle\Entity\Gouvernorat",inversedBy="villes")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="id_gouvernorat", referencedColumnName="id")
 * })
 */
private $idGouvernorat;
}

在名为 Etablissement 的第三个实体中,我有字符串 gouvernorat 和字符串字符串 ville.So 我正在尝试创建 EtablissementType。此表格包含 子 gouvernorat 和 ville 的两个实体类型 简要复制:

class EtablissementType extends AbstractType
{  

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
    $builder
        ->add('nom')           
        ->add('gouvernorat', EntityType::class, array(
            'class' => 'EntiteBundle\Entity\Gouvernorat',
            'choice_label' => 'name',
            'multiple' => false
        ))          
        ->add('ville',EntityType::class,
            array(
                'class' => 'EntiteBundle\Entity\Ville',
                'choice_label' => 'name',
                'multiple' => false
        ))            
        ->add('Enregistrer',SubmitType::class)
        -> setMethod('POST');       
}

当我 select gouvernorat 我希望这个 gouvernorat 的所有城市都加载到第二个 ChoiceType 所以我添加了这个事件:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
            //$builder-> ...

            $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) {
                $form = $event->getForm();

                $data = $event->getData();                    
                $gouv = $data-> getGouvernorat();
                $villes = null === $gouv ? array() : $gouv->getVilles();
                $names = array_map(function ($value) {
                    return  $value['name'];
                }, $villes);

                $form->add('ville', ChoiceType::class,
                    array(
                    'choices' => $names
                ));
            }
        );
    }

数据的快捷方式(json格式):

[
{
    "id": 1,
    "name": "ARIANA",
    "villes": [
        {
            "id": 1,
            "name": "RAOUED",
            "idGouvernorat": null
        },
        {
            "id": 2,
            "name": "SIDI THABET",
            "idGouvernorat": null
        },
        {
            "id": 3,
            "name": "ARIANA VILLE",
            "idGouvernorat": null
        },
        {
            "id": 4,
            "name": "LA SOUKRA",
            "idGouvernorat": null
        },
        {
            "id": 5,
            "name": "KALAAT LANDLOUS",
            "idGouvernorat": null
        },
        {
            "id": 6,
            "name": "ETTADHAMEN",
            "idGouvernorat": null
        },
        {
            "id": 7,
            "name": "MNIHLA",
            "idGouvernorat": null
        }
    ]
},
{
    "id": 2,
    "name": "BEJA",
    "villes": [
        {
            "id": 8,
            "name": "BEJA NORD",
            "idGouvernorat": null
        },
        {
            "id": 9,
            "name": "NEFZA",
            "idGouvernorat": null
        },
        {
            "id": 10,
            "name": "GOUBELLAT",
            "idGouvernorat": null
        },
        {
            "id": 11,
            "name": "MEJEZ EL BAB",
            "idGouvernorat": null
        },
        {
            "id": 12,
            "name": "AMDOUN",
            "idGouvernorat": null
        },
        {
            "id": 13,
            "name": "TEBOURSOUK",
            "idGouvernorat": null
        },
        {
            "id": 14,
            "name": "TESTOUR",
            "idGouvernorat": null
        },
        {
            "id": 15,
            "name": "THIBAR",
            "idGouvernorat": null
        },
        {
            "id": 16,
            "name": "BEJA SUD",
            "idGouvernorat": null
        }
    ]
},

等... 问题是第二个 choiceType 总是空的,这意味着 $gouv->getVilles(); 不起作用 问题出在哪里,我没有找到确切的问题,我用symfony documentation--Dynamic Generation for Submitted Forms

<script>
                    var $gouvernorat = $('#etablissement_gouvernorat');
                    // When gouvernorat gets selected ...
                    $gouvernorat.change(function() {
                        // ... retrieve the corresponding form.
                        var $form = $(this).closest('form');
                        // Simulate form data, but only include the selected gouvernorat value.
                        var data = {};
                        data[$gouvernorat.attr('name')] = $gouvernorat.val();
                        // Submit data via AJAX to the form's action path.
                        $.ajax({
                            url : $form.attr('action'),
                            type: $form.attr('method'),
                            data : data,
                            success: function(html) {
                                // Replace current ville field ...
                                $('#etablissement_ville').replaceWith(
                                    // ... with the returned one from the AJAX response.
                                    $(html).find('#etablissement_ville')
                                );
                                // Ville field now displays the appropriate Villes.
                            }
                        });
                    });
                </script>

首先,当您在表单中获取 gouv 数据时,我不确定它是否按预期工作。

替换

$form = $event->getForm();
$data = $event->getData();                 
$gouv = $data->getGouvernorat();

作者:

$form = $event->getForm();
$data = $event->getData();                
$gouv = $data->get('gouvernorat')->getData(); // basically, you get the form data for the gouvernorat field

目前我认为 gouvernorat 没有填充自己的 villes,这些 villes 存储在数据库中(我想)。 现在您将需要检查您的 $data(它是一个 Etablissement 实例)的 getGouvernorat 方法是否 returns 一个 Gouvernorat 实例。 如果是,您将从您的数据库中获取此 gouvernerat,以便访问其所有城市。

if (!is_null($data->getGouvernorat())) {
    $persistedGouvernorat = $gouvernoratRepository->find($event->getData()->getGouvernorat());;
    if (!is_null($persistedGouvernorat)) {
        $gouverorat = $persistedGouvernorat;
    }
}
$villes = $gouvernorat->getVilles();

那么我认为你可以解决你的问题。