Как получить только измененные объекты после отправки?

У меня есть коллекция форм, как в приведенном ниже коде, что приводит к форме, которая выглядит следующим образом (с двумя примерами записей):

Как получить только измененные объекты после отправки?

При нажатии кнопки «Отправить» данные, которые я предоставил экземпляру формы (построителя), обновляются соответствующим образом.

Проблема: Проблема в том, что список может быть довольно длинным, поэтому мне нужен способ узнать, какие экземпляры были обновлены.

Я думал о сохранении клона исходных данных (здесь $leadPartnerList в моем сеансе. Но это не кажется правильным.

Предоставляет ли symfony (в частности, конструктор форм) такую ​​функциональность из коробки? Или что было бы эффективным решением, чтобы узнать, какие поля в форме были обновлены, а какие нет?

Моя ветка:

{% block content %}

<div>

    {{ form_start(form) }}
    {% for partner in lead_partners %}
        {{ form_row(partner.name) }}
    {% endfor %}
    {{ form_end(form) }}

</div>

{% endblock content %}

Мой код контроллера:

public function overview(Request $request, \App\Utility\LeadPartnerLoader $LeadPartnerLoader)
{
    $leadPartnerList = $leadPartnerLoader->loadAll();
    $formBuilderData = [
        'lead_partners' => $leadPartnerList
    ];

    $listForm = $formFactory->createNamedBuilder('listForm', FormType::class, $formBuilderData)
        ->add('lead_partners', CollectionType::class, [
            'entry_type' => LeadPartnerFormType::class,
            'allow_add' => true
        ])
        ->add('submit', SubmitType::class, [
            'label' => 'Submit Changes'
        ])
        ->getForm();

    ... handleRequest and so on and so forth...
}

И тип формы (LeadPartnerFormType):

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => LeadPartner::class,
    ));
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name', TextType::class);
}

$leadPartnerList имеет тип array с экземплярами LeadPartner в каждой записи массива.

ПОЖАЛУЙСТА, ОБРАТИ ВНИМАНИЕ: Я здесь не использую Doctrine!

@Fabian Фабиан, я не использую Doctrine.

user6629162 07.02.2019 14:19

Если ваш контроллер следует типичному потоку, вы сначала получаете список сущностей, передаете их в форму, а затем запускаете запрос дескриптора. Если вы клонируете список до обработки запроса, у вас будут копии до и после для сравнения. Сеансы не нужны. И хотя я понимаю, что вы не используете Doctrine, возможно, стоит прочитать об их политики отслеживания изменений просто для идей. Можно также рассмотреть возможность создания сущностями события "changed".

Cerad 07.02.2019 14:38

Я почему-то не увидел твой код контроллера. Рано утром здесь. Просто клонируйте $leadPartnerList перед вызовом запроса дескриптора. Нет необходимости хранить его в сеансе. И хотя это не по теме, передача $leadPartList в качестве данных опции выглядит странно. Возможно, вы захотите увидеть пример коллекции в документации для более чистого подхода.

Cerad 07.02.2019 14:57

@Cerad Это не данные опций: createNamedFormBuilder и createFormBuilder имеют другой интерфейс. Кроме того, простое клонирование не будет работать, потому что набор данных, полученный loadAll(), может измениться между отображением формы и ее отправкой, поэтому у меня будет клон другого набора данных, чем тот, который я использовал для отображения формы в первый раз, когда она была отправлена.

user6629162 07.02.2019 15:19

Вы не совсем понимаете процесс. Ваш метод контроллера вызывается дважды. Один раз для GET, чтобы показать пользователю эти данные, а затем второй раз для POST, когда пользователь отправляет. Итак, вы проверяете изменения внутри блока $form->isValid().

Cerad 07.02.2019 15:31

@Cerad Вот что я имею в виду. Второй раз, когда вызывается метод get контроллера, это также второй раз, когда вызывается $leadPartnerList = $leadPartnerLoader->loadAll(); get. И мне нужно состояние $leadPartnerList из первого запуска, чтобы сравнить его с результатами, отправленными пользователем через форму во время второго запуска (и, как вы сказали, сравнение происходит в блоке $form->isValid()). Может быть, я неправильно вас понял (или жизненный цикл Symfony)?

user6629162 07.02.2019 15:43

Хорошо. Вероятно, вы ищете оптимистическая блокировка. Каждая таблица получает столбец версии. Вы настраиваете все так, что каждое обновление приводит к увеличению версии. Вы отправляете номер версии в браузер как часть вашей формы. Когда форма отправляется, вы сравниваете текущие версии базы данных с первоначально отправленными и предпринимаете соответствующие действия, если они отличаются.

Cerad 07.02.2019 16:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
8
57
1

Ответы 1

Используйте Symfony EventListener или EventSubscriber. См.: https://symfony.com/doc/current/doctrine/event_listeners_subscribers.html

Подробности пожалуйста. Ответы только по ссылкам не приветствуются, как правило, быстро отвергаются. Могу добавить, что вопрос не очень ясен. Только после прочтения комментариев становится очевидным, что желательно знать, какие сущности изменились из другого процесса, пока пользователь просматривает форму. События вряд ли помогут в этом.

Cerad 08.02.2019 14:00

Другие вопросы по теме