Как передать данные из FormType parent в FormType child

#forms #symfony #conditional-statements #entity-relationship

#формы #symfony #условные операторы #сущность-отношение

Вопрос:

У меня есть форма, которая проходит в несколько этапов, в том числе :

Шаг 1: простая форма, основанная на сущности 1, которая записывает первую часть набора данных. Шаг 2: родительская форма (на основе объекта 1 на шаге 1), которая реализует дочернюю форму (на основе объекта 2) => CollectionType . Родительская форма ($builder) содержит данные с шага 1, но не дочернюю форму.

Моя цель проста: моя дочерняя форма содержит ChoiceType, который должен меняться в зависимости от заданного

Моя проблема: передать дочерней форме часть данных, которые есть в родительской форме ($builder-> getData()), чтобы установить условие опции для моего ChoiceType.

Я искал решения, но не нашел никакого результата. Поэтому я думаю, что моя проблема — это не ошибка, а плохой подход с моей стороны.

Я тестировал :

 //PARENT
public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('wans', CollectionType::class,
                [
                    'entry_type' => WanDType::class,
                    'entry_options' => [
                        'label' => false,
                        'data' => $builder->getData() // <- here
                    ],
                ]);
    }

//ENFANT
public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $ma_valeur = $builder->getData()->getValue(); //<- here
        if(in_array($ma_valeur, ['1'])) { //<- here
            $builder->add('profil', ChoiceType::class, [
                'choices' => [
                    [...]
                ],
                'label' => false,
            ]);
        } else { //<- here
            $builder->add('profil', ChoiceType::class, [
                'choices' => [
                    [...]
                ],
                'label' => false,
            ]);
        } //<- here
    }
  

=> Я получаю сообщение об ошибке, объясняющее, что мой data_class не соответствует моей дочерней форме. Фактически, data_class родительской формы заменил данные дочерней формы. Ошибка предлагает присвоить ей нулевое значение, но это вызывает другие ошибки, и symfony становится все менее и менее счастливым (логично, на мой взгляд, не очень хорошая практика).

=> Я попытался использовать $options . Symfony недоволен, потому что он отказывается добавлять записи key=> значения, которые он не знает в начале координат.

=> Я думал о том, чтобы сделать свое условие в родительской форме. Но условие может меняться со временем, поэтому создание дочерней формы по типу условий, на мой взгляд, не является хорошей практикой.

=> Я также думал о создании этого поля непосредственно в представлении. Но это также не оптимально в соответствии с эволюциями.

=> Я протестировал несколько вещей, которые бесполезно упоминать здесь, каждый раз с отрицательным результатом.

Я сильно сомневаюсь, что SensioLabs не думали о таких вещах. Мне, вероятно, не нужно быть далеко, если кто-нибудь знает, как объяснить, это было бы замечательно.

Спасибо за вашу помощь 🙂

====================================================

РЕДАКТИРОВАТЬ тест 1

 public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        dump($event->getForm()->getParent()->getData());
        die('ok');
    });
    die('ok2');
}
  

Ответ №1:

Итак. Я не нашел это очень интуитивно понятным. Ничто не объясняет, как нужно воспринимать этот метод в контексте коллекции, когда нужно повлиять на сущность, содержащуюся в коллекции.

Итак, мы не заботимся о концепции родительской и дочерней формы. Это нужно только для вмешательства в форму, на которую влияет наша модификация (если это дочерний элемент, он будет в дочернем элементе FormType).

По сути, это дает следующее:

 public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add([....]); // without the fields I want to modulate.

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

        if(in_array($wan->getEquipment()->->getValue(),['1'])) {
            $event->getForm()->add('profil', ChoiceType::class, [
                'choices' => [
                    [...]
                ],
                'label' => false,
            ]);
        } else {
            $event->getForm()->add('profil', ChoiceType::class, [
                'choices' => [
                    [...]
                ],
                'label' => false,
            ]);
        }
    });
}
  

Ответ №2:

Я думаю, что вы хотите сделать что-то подобное, может предоставить: https://symfony.com/doc/current/form/dynamic_form_modification.html

с помощью этого вы сможете изменять свою форму на основе предоставленных данных

Комментарии:

1. Спасибо за ваше предложение. Я видел эту документацию. Только она использует простую форму. Вне меня я хочу повлиять на вложенную дочернюю форму тем, что содержит родительская форма. Я не знал, как применить эти решения к моим потребностям: /

2. возможно, с помощью $event->getForm()->getParent()->getData()

3. Я вижу. Но как мне передать событие $, которое я создаю в EquipmentDType (родительском), в WanDType (дочернем)? Проблема остается той же, верно?

4. я думаю, вам нужно только добавить событие внутри дочернего элемента, нет необходимости использовать его в родительском типе формы

5. ОК. Хорошо. В моей дочерней форме (WanDType) я протестировал. Я поместил в основной пост «РЕДАКТИРОВАТЬ тест 1». Возможно, я делаю это неправильно, потому что это не работает. Он показывает мне ok2, не показывая мне остальное.