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

При нажатии кнопки «Отправить» данные, которые я предоставил экземпляру формы (построителя), обновляются соответствующим образом.
Проблема: Проблема в том, что список может быть довольно длинным, поэтому мне нужен способ узнать, какие экземпляры были обновлены.
Я думал о сохранении клона исходных данных (здесь $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.
Если ваш контроллер следует типичному потоку, вы сначала получаете список сущностей, передаете их в форму, а затем запускаете запрос дескриптора. Если вы клонируете список до обработки запроса, у вас будут копии до и после для сравнения. Сеансы не нужны. И хотя я понимаю, что вы не используете Doctrine, возможно, стоит прочитать об их политики отслеживания изменений просто для идей. Можно также рассмотреть возможность создания сущностями события "changed".
Я почему-то не увидел твой код контроллера. Рано утром здесь. Просто клонируйте $leadPartnerList перед вызовом запроса дескриптора. Нет необходимости хранить его в сеансе. И хотя это не по теме, передача $leadPartList в качестве данных опции выглядит странно. Возможно, вы захотите увидеть пример коллекции в документации для более чистого подхода.
@Cerad Это не данные опций: createNamedFormBuilder и createFormBuilder имеют другой интерфейс. Кроме того, простое клонирование не будет работать, потому что набор данных, полученный loadAll(), может измениться между отображением формы и ее отправкой, поэтому у меня будет клон другого набора данных, чем тот, который я использовал для отображения формы в первый раз, когда она была отправлена.
Вы не совсем понимаете процесс. Ваш метод контроллера вызывается дважды. Один раз для GET, чтобы показать пользователю эти данные, а затем второй раз для POST, когда пользователь отправляет. Итак, вы проверяете изменения внутри блока $form->isValid().
@Cerad Вот что я имею в виду. Второй раз, когда вызывается метод get контроллера, это также второй раз, когда вызывается $leadPartnerList = $leadPartnerLoader->loadAll(); get. И мне нужно состояние $leadPartnerList из первого запуска, чтобы сравнить его с результатами, отправленными пользователем через форму во время второго запуска (и, как вы сказали, сравнение происходит в блоке $form->isValid()). Может быть, я неправильно вас понял (или жизненный цикл Symfony)?
Хорошо. Вероятно, вы ищете оптимистическая блокировка. Каждая таблица получает столбец версии. Вы настраиваете все так, что каждое обновление приводит к увеличению версии. Вы отправляете номер версии в браузер как часть вашей формы. Когда форма отправляется, вы сравниваете текущие версии базы данных с первоначально отправленными и предпринимаете соответствующие действия, если они отличаются.




Используйте Symfony EventListener или EventSubscriber. См.: https://symfony.com/doc/current/doctrine/event_listeners_subscribers.html
Подробности пожалуйста. Ответы только по ссылкам не приветствуются, как правило, быстро отвергаются. Могу добавить, что вопрос не очень ясен. Только после прочтения комментариев становится очевидным, что желательно знать, какие сущности изменились из другого процесса, пока пользователь просматривает форму. События вряд ли помогут в этом.
Возможный дубликат Есть ли встроенный способ получить все измененные/обновленные поля в объекте Doctrine 2?