Symfony EasyAdmin 3自定义动态日程表单提交问题:数据接收与存储求助
解决EasyAdmin 3自定义动态表单的提交与数据处理问题
嘿,我来帮你搞定这个问题!你遇到的302跳转和数据收集难题,核心原因是自定义表单没和EasyAdmin的原有流程对接好,加上表单命名、提交逻辑没处理到位。下面一步步拆解解决:
1. 修复表单提交基础问题(解决302跳转)
你手动写的<form>标签缺少正确的action、method和CSRF令牌,这就是导致无意义302跳转的根源。EasyAdmin的new/edit页面已经自带表单上下文,我们应该复用它而不是从头构建表单:
修改你的new.html.twig(编辑页edit.html.twig同理),继承EasyAdmin对应模板并复用表单结构:
{# admin/horarios/new.html.twig #} {% extends '@!EasyAdmin/crud/new.html.twig' %} {% block body_javascript %} {{ parent() }} {# 保留EasyAdmin原有JS逻辑 #} <script type="text/javascript"> $( document ).ready(function() { var maxField = 9999; var addButton = $('.add_button'); var wrapper = $('.field_wrapper'); // 重点:修改name为数组格式,方便后端批量接收数据 var fieldHTML = '<div class="mt-2">' + '<input type="time" name="horarios[lunes][]" value="" class="form-control d-inline-block w-auto me-2"/>' + '<input type="time" name="horarios[lunes][]" value="" class="form-control d-inline-block w-auto me-2"/>' + '<a href="javascript:void(0);" class="remove_button">' + '<img src="remove-icon.png"/>' + '</a>' + '</div>'; var x = 1; $(addButton).click(function(){ if(x < maxField){ x++; $(wrapper).append(fieldHTML); } }); $(wrapper).on('click', '.remove_button', function(e){ e.preventDefault(); $(this).parent('div').remove(); x--; }); }); </script> {% endblock %} {% block form %} {# 复用EasyAdmin的表单框架,自动生成正确的action、method和CSRF令牌 #} {{ parent() }} {# 添加你的动态时间字段区域 #} <div class="field_wrapper mt-3"> <div> <input type="time" name="horarios[lunes][]" value="" class="form-control d-inline-block w-auto me-2"/> <input type="time" name="horarios[lunes][]" value="" class="form-control d-inline-block w-auto me-2"/> <a href="javascript:void(0);" class="add_button" title="Add field"><img src="add-icon.png"/></a> </div> </div> {% endblock %}
这样修改后,表单会自动对接EasyAdmin的提交路由(新建对应create动作,编辑对应update动作),且自带CSRF防护,不会再出现无意义的302跳转。
2. 确定数据提交的处理方法
在EasyAdmin 3中:
- 新建实体时,提交数据会进入
CrudController的createEntity方法 - 编辑实体时,提交数据会进入
updateEntity方法
你只需要在HorariosCrudController中重写这两个方法,就能获取并处理动态提交的时间数据:
<?php namespace App\Controller\Admin; use App\Entity\Horarios; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use Symfony\Component\HttpFoundation\Request; class HorariosCrudController extends AbstractCrudController { public function configureCrud(Crud $crud): Crud { return $crud ->overrideTemplates([ 'crud/edit' => 'admin/horarios/edit.html.twig', 'crud/new' => 'admin/horarios/new.html.twig', ]) ; } // 处理新建实体的提交数据 public function createEntity(string $entityFqcn) { $horario = new Horarios(); $this->processHorariosData($horario); return $horario; } // 处理编辑实体的提交数据 public function updateEntity($entityManager, $entity): void { $this->processHorariosData($entity); $entityManager->flush(); } // 提取通用数据处理逻辑,避免重复代码 private function processHorariosData(Horarios $horario) { $request = $this->getRequest(); // 获取前端提交的动态时间数组 $horariosData = $request->request->get('horarios'); if (!$horariosData || !isset($horariosData['lunes'])) { return; } // 按每两个输入为一组(开始时间+结束时间)处理周一的时间段 $lunesTimes = $horariosData['lunes']; for ($i = 0; $i < count($lunesTimes); $i += 2) { if (!isset($lunesTimes[$i+1])) { continue; // 跳过不完整的时间对 } $startTime = $lunesTimes[$i]; $endTime = $lunesTimes[$i+1]; // 这里根据你的Horarios实体结构,把时间写入数据库 // 示例:假设实体有添加时间段的方法 // $horario->addLunesSlot(new HorarioTimeSlot($startTime, $endTime)); } } public static function getEntityFqcn(): string { return Horarios::class; } }
3. 关键细节提醒
- 字段命名规范:把
field_name['lunes']改成horarios[lunes][],后端能直接拿到数组,方便按组处理时间对。 - CSRF防护:复用EasyAdmin表单框架会自动生成CSRF令牌,避免提交被Symfony的安全机制拦截。
- 代码复用:把数据处理逻辑提取到单独方法,让新建和编辑流程保持一致,后续维护更方便。
这样修改后,你就能正常收集动态添加的时间数据,顺利写入Horarios数据表了!
内容的提问来源于stack exchange,提问作者Rafa Alvarez-Ossorio Martin
相关产品推荐
相关产品推荐

