Doctrine orm 打印新分配的实体';在使用CollectionType提交表单后立即使用s id 不久说
在提交新项目时,Symfony会处理POST数据,但新持久化的项目没有在其相应的隐藏字段值属性中填充其id,而是缺少值属性 手术: 我已经实现了一些添加/编辑/删除功能,使用户可以使用管理一个“城市”实体池。Doctrine orm 打印新分配的实体';在使用CollectionType提交表单后立即使用s id 不久说,doctrine-orm,symfony-forms,symfony,Doctrine Orm,Symfony Forms,Symfony,在提交新项目时,Symfony会处理POST数据,但新持久化的项目没有在其相应的隐藏字段值属性中填充其id,而是缺少值属性 手术: 我已经实现了一些添加/编辑/删除功能,使用户可以使用管理一个“城市”实体池。 添加新城市时: 我确保每个现有条目都有一个隐藏字段,其中包含实体的id(pk)以及可编辑的常规属性,以便正确更新现有实例 提交表格时,数据可用[ok] 持续循环和后续刷新成功更新数据库[确定] 表单将使用新添加的城市再次呈现 除了任何新提交的城市的隐藏字段缺少«value»属性之外,所
添加新城市时:
- 我确保每个现有条目都有一个隐藏字段,其中包含实体的id(pk)以及可编辑的常规属性,以便正确更新现有实例
- 提交表格时,数据可用[ok]
- 持续循环和后续刷新成功更新数据库[确定]
- 表单将使用新添加的城市再次呈现
在flush之后立即访问对象getter将返回相应的最新属性。新插入的记录ID已填充 所以我希望Doctrine在刷新时更新新保存的城市对象,但看起来什么都没有发生表单似乎没有意识到新的插入。这是因为表单数据在处理请求后具有不变性吗? 注意:至少,当重新加载页面时(在不发布两次数据的情况下到达相同的URL),隐藏字段最终会打印其属性值和相应实体的id 有人能帮我找出这里需要做什么,以便在提交后立即正确呈现(新插入项的)隐藏字段(使用包含预期实体id的«value»属性) 控制器… 关联模板
{{#…}
{{form_start(form)}}
{集合%中的项的%s}
{{form_widget(item)}
{%endfor%}
{{'按钮添加标题'| trans}}
提交
{{form_end(form)}}
这很清楚,谢谢
编辑
在集合的条目\u选项中,by\u reference
设置为true
我做过的测试表明:它只在那里有影响。如果为True,则可以更新数据库中的相应(现有)记录。另一方面,false会阻止进行映射,从而导致数据库中出现重复条目。
在收藏本身上设置
(按_reference设置)
似乎根本没有任何作用。也就是说,新记录实际上是持久的,但是修改这个新创建的元素会导致随机行为(由于允许删除而被删除,发布了重复条目)。仍然开发工具DOM树不显示隐藏字段的
值
属性,导航器源快捷键Ctrl+u也不显示。一旦发出新的GET请求,Value属性就会神奇地出现。
这里肯定有我不明白的事情。:/
最后,我发现确保表单正确填充隐藏字段的唯一方法是命令
$this->redirect($this->generateUrl($_-route))
afterflush()
查看文档的最后一个段落–它特别是关于CollectionType的。这可能与您的问题无关,但您正在控制器中的CollectionType上手动重新实现'by_reference'=>true
的语义。@Lumen感谢您抽出时间,我已经编辑了我的线程。
<?php
// ...
/**
* @Route("/cities", name="admin_config_cities")
*/
public function configureCitiesAction(Request $request)
{
# Retrieving existing cities
$em = $this->getDoctrine()->getManager();
$cities = $em->getRepository('AppBundle:City')->findAll();
# Associate cities ids with corresponding objects
$sorted = [];
array_walk($cities, function ($value, $key) use (&$sorted) {
$sorted[ $value->getId() ] = $value;
});
# Initialize form
$citiesForm = $this->createForm(
CollectionType::class,
$cities,
[
'entry_type' => CityType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
# I thought "mapped" option would do the trick.
# worse, seems to do nothing
'mapped' => true,
'label' => false,
'entry_options' => [
'label' => false,
'by_reference'=>true
]
]
);
if ($request->isMethod('POST')) {
$citiesForm->handleRequest($request);
if ($citiesForm->isValid()){
# Persist any submitted datas
foreach( $citiesForm->getData() as $city ){
$id = $city->getId();
if ($id && array_key_exists($id,$sorted)) {
unset($sorted[$id]);
}
$em->persist($city);
}
# Remove discared cities
foreach( $sorted as $removed ){
$em->remove($removed);
}
$em->flush();
}
}
# TODO: find the way to make newly added cities to be rendered
# along with their ID available inside an hidden field's attribute
# right after submission (without the need of a refresh)
return $this->render('AppBundle:admin:config/cities.html.twig', [
'form' => $citiesForm->createView()
]);
}
//…
$builder->add( 'id', HiddenType::class, [ 'required'=>false ])
//…
{# … #}
{{ form_start(form) }}
<div data-prototype="{{ form_widget(collection.vars.prototype)|e }}">
{% for item in collection %}
{{ form_widget(item) }}
{% endfor %}
<p>
<a class="btn btn-default btn-sm" title="{{ 'button-add-title'|trans }}">{{ 'button-add-caption'|trans }}</a>
</p>
</div>
<p class="text-right">
<button type="submit">Submit</button>
</p>
{{ form_end(form) }}