如何禁用 EntityType 的实体自动加载?

How to disable automatic loading of entities for EntityType?

我正在 Symfony 4 应用程序中编写注册表。

我有一个字段 ZipCode 和一个字段 City。 城市列表和邮政编码位于名为 communes 的 table 中。 当用户填写表格时,我希望他只填写他的邮政编码,然后将具有此邮政编码的城市加载到列表中。

我这样做了

RegistrationFormType.php

 ->add("codePostal", TextType::class, [
                "mapped"=>false, 
                "label"=>"Code postal",
                ])
 ->add('commune', EntityType::class, [
                'class' => Commune::class,
                'choice_label' => 'nom',
                'placeholder' => "Choisir une ville",
            ])

然后在模板中我使用 Jquery 和 Json 调用来更改列表 register.html.twig

<script>
let dropdownCommune = $('#registration_form_commune');
dropdownCommune.empty();

$("#registration_form_codePostal").change(function() {
  $.ajax({
    url: "{{ path('app_commune_json_list_communes') }}", // point to server-side PHP script
    dataType: 'json',
    data: {
      data: this.value
    },
    type: 'POST',
    success: function(data) {
      dropdownCommune.empty();
      dropdownCommune.prop('selectedIndex', 0);

      $.each(data, function(key, entry) {
        //console.log(entry.departement);
        dropdownCommune.append($('<option></option>').attr('value', entry.id).text(entry.nom));
      });
    }
  });
});
</script>

这行得通,但我的问题是 commune 字段会在第一次加载页面时加载数据库中的所有城市。这需要很长时间,我确信有办法阻止它,但我找不到办法。

您可以在表单中使用查询生成器,并通过 setMaxResults() 将结果限制为 0:

->add('commune', EntityType::class, [
                'class' => Commune::class,
                'query_builder' => function (EntityRepository $er) {
                        return $er->createQueryBuilder('c')
                            ->setMaxResults(0);
                    },
                'choice_label' => 'nom',
                'placeholder' => "Choisir une ville",
            ])

并且不要忘记添加此用途:

use Doctrine\ORM\EntityRepository;

我认为这样做的一种方法是查询 select 只有城市的 ID 和名称,并在树枝中使用 froeach,会很快。 作为第二种解决方案,建议您使用:

   $(window).load(function () {
        //Ajax query 
      beforeSend: function () {
            $('#loading').append('<div id="loading""></div>');
      },
      complete: function() {
            $('#loading').hide();
      },
   });