Загрузка объекта в поле в зависимости от выбора в другом поле. Symfony PRE_SET_DATA Слушатель событий - PullRequest
0 голосов
/ 06 ноября 2018

Привет, я получил мою форму OrderType.

Вот мой код:

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_DATA загрузил адреса доставки, назначенные клиенту, в сущности ClientsShippings в зависимости от выбранного клиента. Я прочитал это несколько раз на symfony.com, но я не могу полностью понять эти события.

Может ли кто-нибудь помочь мне запустить его, дайте мне пример того, как он работает. Может быть, я думаю об этом совершенно по-другому.


  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) {
      if(isset($client->getJson()["client"]["firma"]))
      {
        $firma = $client->getJson()["client"]["imie"];
        }
        else {
          $firma = "";
          }
    return  ''.$firma.' '.$client->getJson()["client"]["imie"] .' '. $client->getJson()["client"]["nazwisko"].'';
      },
    'label' => 'Wybierz klienta'

                ))

        ->add('product', EntityType::class, array(
    'data' => $options['product'],
    'mapped' => false,
    'multiple' => true,
    'class' => Products::class,
    'attr' => ['class' => 'chosen-select','data-placeholder'=>'Wybierz produkt'],
    'choice_label' => function ($product) {
        return  ''.$product->getJson()["products"]["name"] .' | Stan Magazynowy: '.$product->getJson()["products"]["stock"].'';
      },
  'label' => 'Wybierz produkty'

        ))

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

    $builder->get('client')->addEventListener(
      FormEvents::POST_SUBMIT,
      function (FormEvent $event)
      {
        $form = $event->getForm();

        $form->getParent()->add('shipping', EntityType::class, [
          'class' => ClientsShippings::class,
          'placeholder' => 'Wybierz adres dostawy',
          'choices' => $form->getData()->getclientsShippings()
        ]);
      }
    );


    }

1 Ответ

0 голосов
/ 06 ноября 2018

Форма Symfony имеет 2 основных использования:

  1. Создание новой сущности (Form::submit() называется)
  2. Редактирование существующего объекта (Form::setData() и Form::Submit() называются)

Примечание: В обоих случаях Form::handleRequest() вызывается перед Form::submit(), чтобы проверить, может ли запрос быть отправлен.

У нас есть 2 основных категории событий формы:

  • события во время предварительного заполнения форм (используется только для редактирования формы объекта)
  • события при отправке формы (используется как для новых, так и для редактирования форм сущностей)

1. Предварительное заполнение формы данными модели

PRE_SET_DATA

Событие PRE_SET_DATA получает значение данных, с которого вы начинаете (объект Order в вашем случае), и отправляется непосредственно перед заполнением формы данными объекта-сущности.

Вы можете использовать это событие для:

  • Изменить данные формы во время заполнения
  • Добавить или удалить поля формы

POST_SET_DATA

Это событие вызывается сразу после вызова метода Form::setData() и может использоваться для:

  • Считайте данные, предварительно заполнив форму

Оба события POST_SET_DATA и POST_SET_DATA отправляются во время предварительного заполнения данных формы.

2. Отправка формы

PRE_SUBMIT

Это срабатывает при вызове Form::submit() или Form::handleRequest(). Это событие может быть использовано для:

  • Изменить данные, полученные из запроса
  • Добавить или удалить поля перед отправкой данных

ВВЕСТИ

Это событие отправляется после PRE_SUBMIT и во время Form::submit (после нормализации данных модели и вида и до денормализации). Вы можете использовать это событие для:

  • Изменить данные после нормализации.

POST_SUBMIT это событие отправляется после Form::submit(). Вы можете использовать это событие для:

  • Получить данные после денормализации.

Ответ на ваш вопрос

Вы должны использовать 2 прослушивателя событий, один для PRE_SET_DATA и один для POST_SUBMIT:

OrderType

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), чтобы обновить список shipping в соответствии с выбранным клиентом.

...