如何在EasyAdmin3和Symfony5的PHP控制器中获取Twig内Google Places的JS变量
实现方案
- 第一步:修改表单类,新增隐藏字段
首先在你对应的表单类型中添加一个未映射的隐藏字段,用于接收前端传来的Google Places数据,不需要对应实体字段:
// 示例:AddressType.php 地址表单类 use Symfony\Component\Form\Extension\Core\Type\HiddenType; // ... ->add('placeData', HiddenType::class, [ 'mapped' => false, // 不映射到实体字段 'required' => false, 'attr' => ['id' => 'place_data'] ])
- 第二步:修改Twig模板的JS逻辑
首先修正你原代码的错误:JS中字符串拼接用+而非.,我们直接将完整的place对象转成JSON字符串存入上一步添加的隐藏域即可,修改后完整代码如下:
{% form_theme form 'form/form_theme.html.twig' %} {% block address_form_widget %} <!-- 地址输入框,确保id为autocomplete --> <input type="text" id="autocomplete" placeholder="输入地址"> <div id="details"></div> <script> let autocomplete; function initAutocomplete() { autocomplete = new google.maps.places.Autocomplete( document.getElementById('autocomplete'), { types: ['establishment'], componentRestrictions: {'country' : ['ES']}, fields: ['place_id', 'geometry', 'name'] } ); autocomplete.addListener('place_changed', onPlaceChanged); } function onPlaceChanged() { var place = autocomplete.getPlace(); if(!place.geometry) { document.getElementById('autocomplete').placeholder = '请输入有效地点'; } else { // 把place对象转成JSON字符串存入隐藏域 document.getElementById('place_data').value = JSON.stringify(place); // 前端展示选中的地址信息 document.getElementById('details').innerHTML = place.name + ' 坐标:' + place.geometry.location.lat() + ',' + place.geometry.location.lng(); } } </script> <script src="https://maps.googleapis.com/maps/api/js?key=你的API密钥&libraries=places&callback=initAutocomplete" async defer></script> {% endblock %}
- 第三步:在EasyAdmin控制器中接收数据
在你对应实体的CrudController中重写persistEntity方法,即可拿到提交的place数据做后续处理:
// 示例:AddressCrudController.php use Doctrine\ORM\EntityManagerInterface; // ... public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void { $request = $this->getContext()->getRequest(); // 把your_form_name替换为你实际的表单名,不清楚可以打印$request->request->all()查看参数结构 $placeData = $request->request->all()['your_form_name']['placeData'] ?? null; if ($placeData) { // 解析JSON拿到完整place数据 $place = json_decode($placeData, true); // 按你的业务需求使用数据即可,比如赋值给实体字段 $entityInstance->setLatitude($place['geometry']['location']['lat']); $entityInstance->setLongitude($place['geometry']['location']['lng']); $entityInstance->setPlaceId($place['place_id']); $entityInstance->setAddress($place['name']); } parent::persistEntity($entityManager, $entityInstance); }
如果你不需要等待表单整体提交,也可以在onPlaceChanged方法里直接用fetch把place数据POST到你自定义的Symfony路由对应的控制器方法里异步处理。
内容的提问来源于stack exchange,提问作者Lorena C.
相关产品推荐
相关产品推荐

