Php 根据另一个字段中的选择将实体加载到字段Symfony PRE_SET_DATA事件侦听器

Php 根据另一个字段中的选择将实体加载到字段Symfony PRE_SET_DATA事件侦听器,php,forms,symfony,entity,Php,Forms,Symfony,Entity,嗨,我拿到我的订单类型表了 这是我的密码: public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('client', EntityType::class, array( 'data' => $options['client'], 'mapped' => false,

嗨,我拿到我的订单类型表了

这是我的密码:

public function buildForm(FormBuilderInterface $builder, array $options)
{
   $builder
              ->add('client', EntityType::class, array(
              'data' => $options['client'],
              'mapped' => false,
              'attr' => ['class' => 'chosen-select','data-placeholder'=>'Wybierz klienta'],
              'class' => UserDetails::class,
              'choice_label' => function ($client) {
              return  ''.$firma.' '.$client->getJson()["client"]["imie"] .' '. $client->getJson()["client"]["nazwisko"].'';
               },
              'label' => 'Wybierz klienta'))


               ->add('save', SubmitType::class, [
               'label' => 'Zapisz',
               'attr' => ['class' => 'btn btn-primary pull-right']]) ;

    $builder->addEventListener( 
              FormEvents::PRE_SET_DATA,
                function (FormEvent $event) {
                       $form = $event->getForm();
                       $client =$form->get('client')->getData();
                       $shipping = null === $client ? array() : $client->getClientsShippings()->getJson()["clients_shippings"]["name"];

           $form->add('shipping', EntityType::class, array(
               'class' => ClientsShippings::class,
               'placeholder' => '',
               'choices' => $shipping));
             }
           );
}
没有错误,但也没有发生任何事情。我不知道如何实现这一点,在选择EventListener客户端之后,根据所选的客户端,PRE_SET_数据将分配给客户端的配送地址加载到ClientsShippings实体中。 我在symfony.com上读过几次这篇文章,但我不能完全理解这些事件

有人能帮我运行一下吗?让我举个例子说明它是如何工作的。也许我的想法完全不同



Symfony表单有两个主要用途:

  • 创建新实体(
    Form::submit()
    被调用)
  • 编辑现有实体(
    Form::setData()
    Form::Submit()
    被调用)
  • 注意:在这两种情况下,都会在
    Form::submit()
    之前调用
    Form::handleRequest()
    ,以检查请求是否可以提交

    我们有两大类形式事件:

    • 预填充表单期间的事件(仅用于编辑实体表单)
    • 表单提交期间的事件(用于新建和编辑实体表单)
    1.使用模型数据预填充表单 预设置数据

    PRE_SET_DATA
    事件,获取您开始使用的数据的值(
    Order
    对象,在您的情况下),并在表单填充实体对象的数据之前进行调度

    您可以使用此事件来:

    • 在填充期间修改表单数据
    • 添加或删除表单字段
    设置后数据

    此事件在调用
    Form::setData()
    方法后立即激发,可用于:

    • 在预填充表单后读取数据
    POST\u SET\u DATA
    POST\u SET\u DATA
    事件都是在预填充表单数据期间调度的

    2.提交表格 预提交

    当调用
    Form::submit()
    Form::handleRequest()
    时,将触发此命令。此事件可用于:

    • 更改从请求捕获的数据
    • 在提交数据之前添加或删除字段
    提交

    此事件在
    PRE_SUBMIT
    之后和
    Form::SUBMIT
    期间(在模型和视图数据规范化之后和反规范化之前)调度。您可以使用此事件来:

    • 在标准化后更改数据
    提交后提交 此事件在
    表单::submit()之后调度。您可以使用此事件来:

    • 取反规范化后的数据
    回答你的问题 您应该使用两个事件侦听器,一个用于
    设置前数据
    ,另一个用于
    提交后数据

    订单类型

    class OrderType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('client', EntityType::class, array(
                    'class' => UserDetails::class
                ))
                ->add('save', SubmitType::class)
            ;
        
            $modifier = function (FormInterface $form, Client $client = null) {
                $shippings = null === $client ? array() : $client->getClientsShippings();
    
                $form->add('shipping', EntityType::class, array(
                    'class' => ClientsShippings::class,
                    'choices' => $shippings,
                ));
            };
    
            $builder->addEventListener(
                FormEvents::PRE_SET_DATA,
                function (FormEvent $event) use ($modifier) {
                    $orderData = $event->getData();
                    $modifier($event->getForm(), $orderData->getClient());
                }
            );
    
            $builder->get('client')->addEventListener(
                FormEvents::POST_SUBMIT,
                function (FormEvent $event) use ($modifier) {
                    $client = $event->getForm()->getData();
                    $modifier($event->getForm()->getParent(), $client);
                }
            );
        }
    }
    

    您还应该根据所选的客户端进行AJAX调用(一些JavaScript)以更新
    配送
    列表。

    :)好的,甚至可以根据我们在第一次输入中选择的内容动态更改输入字段的值?好的,我现在了解了它的工作原理,但为什么现在我做的是直接发送到控制器的示例POST_SUBMIT,而不是添加字段?我听不懂你的英语。请重新填写你的问题,看这里;这就是问题所在,也是以前的问题,这就是为什么我有这么多问题,
    class OrderType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('client', EntityType::class, array(
                    'class' => UserDetails::class
                ))
                ->add('save', SubmitType::class)
            ;
        
            $modifier = function (FormInterface $form, Client $client = null) {
                $shippings = null === $client ? array() : $client->getClientsShippings();
    
                $form->add('shipping', EntityType::class, array(
                    'class' => ClientsShippings::class,
                    'choices' => $shippings,
                ));
            };
    
            $builder->addEventListener(
                FormEvents::PRE_SET_DATA,
                function (FormEvent $event) use ($modifier) {
                    $orderData = $event->getData();
                    $modifier($event->getForm(), $orderData->getClient());
                }
            );
    
            $builder->get('client')->addEventListener(
                FormEvents::POST_SUBMIT,
                function (FormEvent $event) use ($modifier) {
                    $client = $event->getForm()->getData();
                    $modifier($event->getForm()->getParent(), $client);
                }
            );
        }
    }